Toggle visibility of content in web app - javascript

This question is not about how to toggle a div. But instead how to toggle visibility in a big web app. My web app needs only to run on Chromium (Webkit). The problem I have is probably more related to infrastructure and best practices, and I wonder if anyone has experience with this.
My app runs on node-webkit, which means all files are local, and loading is quick. To feel really snappy, I add all content to the DOM I possibly can. I want to stay away from state changing my app with Javascript, so no $('.view-projects').addClass('visible');. Because it will get messy really soon, and I feel it's not really the task of JS.
Instead the approach I have chosen works like this.
// javascript sample (I actually code in CoffeeScript)
// catch all click events on elements with data-trigger attributes
app.on('view:addProject', function () {
// add a class to the root view
$('#app').addClass('view-addProject');
}):
Markup:
<!-- markup sample -->
<div id="app">
<div class="projects">
<div data-trigger="view:addProject"></div>
<div>etc.</div>
</div>
<div class="addProject">
etc.
</div>
</div>
Css, used as the state machine:
app.view-addProject .addProject {
visibility: visible;
display: block;
}
What I want to know is if other people have tried something like this, have good experiences with other approaches etc. Or maybe I am missing something, I feel I am getting myself in trouble with dynamic content.
Note: I can't simply use show/hide, since my elements use display: -webkit-flex/-webkit-box; etc.

If you want to toggle visibility, here are some alternative approaches:
Control state by changing CSS via the CSSOM
Change state by changing data- attributes
Change state by changing DOM nodeNames

Related

AngularJS shows model text before compilation despite ng-cloak

I'm working on a page that has to run on an embedded android system (in the system webview), and this thing is tragically slow. So slow in fact, that when you load a page, somtimes the model text is still on the page for a good half second before AngularJS gets around to updating all of the bindings. This is annoying and clearly undesirable.
I've added ng-cloak to endless permutations of elements of the page. I've also added the following style to the style sheet:
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
display: none !important;
}
It just doesn't want to cloak the contents, and I think ionic is to blame. Not knowing a lot about AngularJS, I tried writing a directive my-cloak that added a class to the element on compile and pre-link and removed it on post link. It worked better, but it didn't work always.
I've read about some more things I could do like "decorating" the interpolation function (getting out of my depth) and maybe one of the various suggestions listed here (like evalAsync or something like that) but I don't know enough about Angular to understand what those solutions actually do. Coming from a jQuery background is very hard when transitioning to AngularJS.
So any help would be really appreciated. I just want to prevent the undigested text from ever showing on the screen, basically doing what ng-cloak is supposed to do but for slower systems. Thanks!
This is not an answer you are looking for, but there is a good practice to write
<span ng-bind="data"> </span>
(so no {{data}} blinking).
ng-cloak styles already on the page. Look in the header of rendered page with angular app.
you can do something like:
<body ng-show="loaded"></body> and set scope.loaded = true in controller, after data is loaded.

CSS responsive design: hiding doesn't make a page from rendering

Suppose on one page, I have want to show a template in two version depending on the user's device.
For example, I implemented the following code.
<div class="desktop">
<body>
Hi Desktop user
</body>
</div>
<div class="mobile">
<body>
Hi mobile
</body>
</div>
This works okay with media queries but with javascript, I realized that $('body') actually returns both objects. Although the user doesn't see the element because .desktop is set to display:none on mobile deviecs, it seems that the html elements are rendered. In this case, is it still an okay practice or should I avoid doing something like this?
As for me, this is not very good practice. Because you have 2 elements on page, which browser will render. And for him ( browser ) it doesn't meter, visible this element or not.
Your media query from css can do all the same things on one element. And it will be faster. Or use server side to understand what kind of template you should show - mobile or desktop.

Disabling Bootstrap CSS inside a certain container, stop overriding css

I am currently using bootstrap and knockoutjs to display a webpage that has a live preview of some data. For instance, a user enters a title, in a textbox, on the left hand side. Then, the right hand side of the page updates to format that text based on some other settings. So it might be something like <h1>{title}</h1> or it might be <u>{title}</u>. However, all that is requested from the user, at this point, is the title in plain text.
The issue is, as the preview is actually a HTML document created by the users. So, some of the bootstrap CSS overrides the CSS specified by the users. So the above <h1> will inherit bootstraps h1 CSS class, rather than using whatever is in the users HTML template. This means at the time of using the created document, the preview may differ to what is actually happening.
JSFiddle example: http://jsfiddle.net/Piercy/4fcmk/
HTML:
<div class="content">
<h1>Header 1</h1>
<div id="Preview">
<!-- Start Html Template -->
<style>
.header
{
color: red;
}
</style>
<h1 class="header">Header Class</h1>
<!-- End Html Template -->
</div>
</div>
CSS:
.content h1
{
color: blue;
}
The user would expect "Header Class" to be red as they do not know anything about the content css. In my code i am using bootstrap but this shows a simplified version of the issue. Normally, you would just make the CSS more specific but because the user doesn't know about bootstrap (or in the jsFiddle example content) we can't really expect them to modify the CSS.
I need to try figure a way to either stop a certain container (preview div in the jsFiddle) using the stylesheet thats being used by it's parent or figure a way i can modify the bootstrap CSS so that overriding issues are less likely.
Of course, sticking it in an iframe would accomplish this but then I will have issues trying to access and modify the preview.
I am open to all ideas, just want to try find the most appropriate way to deal with this situation. I found this rather difficult to put down on paper so I apologise if it is hard to understand.
To my understanding, there is no way to tell CSS to not inherit styles. However, here's an interesting idea for a workaround.
Take the bootstrap.css file and drop it into your CSS preprocessor of choice (I used LESS).
Next, wrap ALL of the styles with an ID or class of bootstrap like this:
#bootstrap { ...all the bootstrap styles go here. }
Then, save it as a .less file and compile it. Your result will be all the bootstrap styles inheriting from #bootstrap or .bootstrap (depending whether you used an ID or class to wrap bootstrap's styles).
Finally, wrap whatever markup in your template that your users will not be editing in a div and give this div an id of #bootstrap or class of .bootstrap, and include only the bootstrap file we just processed using LESS.
That takes care of the user's CSS not inheriting from bootstrap. However, your users can still write styles that bootstrap will inherit. To get around this, wrap the user's content in an id or class of something like #user or .user and ask them to begin all of their styles with .user > likes this:
.user > h1 {color: red;}
.user > p {font-size: 18px;}
This should separate your HTML template's styles from your users' styles - it just takes a little bit more work from your users.
Here's a jsfiddle to demonstrate:

How to keep user from seeing "ugly" HTML precursor when using jQuery UI and RequireJs?

I'm trying to adapt a jquery-ui codebase to use RequireJs, and I'm deploying it on a much slower (but scalable) virtualized cloud service than the dedicated host I was using before.
My pages are by default an ugly catastrophe of vanilla HTML. The only thing that brings this mess to life are calls to JavaScript functions, which give it the appropriate tab controls and layout. In fact, the page is laid out long and vertical...one section after another...before I call the .tabs() function which folds them up into a single unit with a horizontal control.
(Fairly confident I'm "doing it right" in the jQuery UI mindset. By not building the whole UI through code to start with, it can be at least looked at with JavaScript disabled. Though I doubt anyone is still using Lynx, there are issues of accessibility...or making sure your content is analyzable by search engines. I'll spare you my old man speech about how this is an absurdist way of achieving content/UI separation. :-/)
When I was using <script> tags to load my 3rd party library dependencies and the $(document).ready to run the jQuery UI voodoo, the user never saw the vanilla ugly HTML. Now that I'm using RequireJs, the page.js file lags and loads asynchronously after the HTML...waiting for libraries that aren't really needed for the DOMready handling. The slower server makes this look really awful.
I could of course use CSS styling to hide the ugliness at the outset, and overlay with a "Loading..." graphic until the UI was ready. That's what came to mind first, and a similar approach is suggested here:
Jquery UI interface looks ugly before document.ready
(Note: It seems like such a common problem that I'd almost think there'd be a RequireJs plugin that went ahead and did this. Is there?)
In any case, I didn't seem to have to worry about this before...and I'm wondering if I'm missing some simpler solution. How do you keep users from seeing "ugly" HTML if you're using RequireJs?
I'm with you that you should do some CSS wizardry and then in RequireJs's "kick it off" script, hide it. You should also consider SEO impact and JavaScript disabled scenarios.
Remember, at the end of the day, it's just HTML, CSS, and JavaScript. What ever templating / code generation system you use to get you there, at the end of the day, it's just HTML content, styled with CSS, and animated with JavaScript.
I'd argue that it makes more sense to use something like node-browserify to do all of your Javascript module requires and then stream down the single JS file to the end-user.
Why go through all of the TCP handshakes and HTTP headers to get the same thing at a much lower performance when the client is obviously not intended to be run in an offline mode?
Hey Doc, it hurts when I do this.
Well, then don't do that!
I'm having the same issue with Jquery Mobile and RequireJS.
I first tried following this tip and hid the "ugly HTML" by adding CSS:
.requireJS-init { visibility: hidden;}
.requireJS-init.done { visibility: visible;}
and assiging .requireJS-init when the page fires up and removing it once everything has been loaded by adding another class done (you could remove the initial class, too I guess).
However this causes two problems:
1. Users might have a blank page for a while depending on your content being loaded
2. IE8 fails, because (in my case) Jquery Mobile tries to focus on elements while they are still hidden.
I tried moving around the class form HTML to BODY to elements holding the page content, but nothing really worked.
A much easier CSS-only solution is this:
.ui-mobile-rendering:before {
width: 100%;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
display: block;
height: 100%;
z-index: 0;
background:#fff url(../images/ajax-loader.gif) no-repeat center center;
content: ""
}
The ui-mobile-rendering class is on the body while JQM does it's widget enhnacements. Once the page is done, the class is removed. By adding a fullscreen :before - in this case with the JQM loader as background image - you hide everything on the page until it's rendered. No need for visibility:hidden, IE8 doesn't complain (thank good, IE8 and FF3.6 know :before).

Hidden divs - reducing latency with style display none + javascript

I commonly use hidden divs on my pages until they need to be unhidden with javascript. I used to do the initial hiding with javascript too, but now moved away to hiding them with css to guarantee that the hiding takes place (js disabled in the browser). Also there was a latency issue with js hiding (waiting for the js to load).
My problem is that with css, there's still some latency, and so I end up including the style with the markup like below, and I kind of hate doing it, makes me feel like I'm doing something wrong..
<div style="display:none;">
content
</div>
How often do you guys do this? and is there a way I can get the css or js to somehow load BEFORE the rest of the markup?
Thanks in advance
Include the css in an inline style block at the top of the page:
<style>
.hidden: { display: none; }
</style>
Then annotate your div with the needed class:
<div class="hidden"> ... </div>
The upshot of this approach is that to show the element, you don't need to set display to block, you can just add/remove the class from the element with JavaScript. This works out better because not every element needs display=block (tables and inline elements have different display modes).
Despite what another poster said, it's not bad practice. You should separate your CSS into presentational and functional markup - functional one controls such logical things as whether or not something gets shown, presentational one just determines how to show it. There is no issue putting functional CSS inline to avoid the page jumping around.
I may get hammered for this, but in a lot of apps, when I want to avoid this latency I use inline script tags immediately after the content, like this:
<div id="hidden-div">
content
</div>
<script type="text/javascript">
$('#hidden-div').hide();
</script>
Or if you're not using jQuery:
<div id="hidden-div">
content
</div>
<script type="text/javascript">
document.getElementById('hidden-div').style.display = 'none';
</script>
At first this seems clunky; however, there are a couple of reasons why I take this approach:
The hiding is immediate (no waiting
for the entire DOM to load)
People with JavaScript disabled will
still see the content, whereas if we
hide it with CSS there is no way for
non-JS users to make it visible
again.
Hope this helps!
I would suggest moving your display:none rule to the top of the stylesheet so it's the first or first of a few parsed, though to be honest it would really depend on how many http requests/media resources you have.
You could try throwing the js before the end body tag and making sure the css is at the top, and the css stylesheet that hides those elements is the very first one linked.
Depends on the browser. Opera, WebKit and Konqueror load CSS and JavaScript in parallel (all CSS is loaded before being applied, however).
display:none is the best solution, but you can use inline-css (like in your description) which is directly loaded with the page, if you want to be extra cautious, its bad practice though.

Categories

Resources