Chrome Extension: How do I get rid of the FOUC? - javascript

The essence of the problem is as follows:
There is a page, I need to modify the contents of the browser extensions, you can use jQuery.
Tried $(document).ready(), but then the contents are still displayed for a short period (FOUC). I can not make changes to the page styles on the server.
I'm using the kango framework to build the extension.

Using only ECMAscript, you can't reliably avoid it. You have like no shot if you wait for DOMContentLoaded event, because at that point the DOM is pretty much rendered and displayed (which is what you see for a short period).
Your best shot would be to modify the CSS as soon as possible. If the stylesheet definition gets loaded before the DOM gets rendered and you would have set like
body {
display: none;
}
you would not see anything. You could try like
<body>
<script>
document.body.style.display = 'none';
</script>
<!-- more html -->
</body>
if that is any viable / useable solution for you.

I suggest you to use a combination of CSS and JavaScript. I had the same issue using jQueryUI on a site I'm building and found that a lot of these solutions out there would make the content unavailable to those without JavaScript.
So, here is what I did:
CSS:
.flash #wrapper {
display: none;
}
This sets <div id="wrapper"> to hidden only if it is a decedent of the flash class. So, to keep it from being hidden from those without JavaScript I add the flash class to <html> element. So, it can only be physically hidden if an end-user has JavaScript enabled, otherwise they'll at least have access via the unstyled content.
JavaScript:
$('html').addClass('flash');
$(document).ready(function() {
/* Do all your stuff */
/* When done show the wrapper with the content styled */
$(#wrapper).show();
});
Depending on your pages time to load you might get a little flash, but it won't be a flash of unstyled content, which is rather ugly. In my case I had a jQueryUI menu item that would flash the normal <ul> element first then the menuUI item, and my <div> elements are resized with jQuery so that each <div> column is equal height, but it would flash the different heights first. This fixed it while still giving accessibility to non-JavaScript browsers.

Related

Unstyled text flashes before page fully loads in Firefox

I have a web page which loads inside of a JQuery UI Dialog. When the page loads in Firefox, the plain text appears for a second before all the css and javascript runs. Once everything loads, the text appears properly. Is there a way to prevent the text from showing until all the CSS/JavaScript runs? I have tried turning on and off the visibility but that did not work correctly.
This only seems to happen in Firefox, and not in other browsers.
Some people like to call this the FOUC (Flash Of Unstyled Content). If you are using Google Fonts embedded via javascript (resource) then it adds a class to the html tag that allows you to hide content whilst the scripts are loading using normal rules like html.wf-loading #content{display:none}.
However, in my experience this isn't bombproof though. The only way I've found to fairly consistently achieve no FUOC during is to convert your fonts to BASE64 and embed that directly in your CSS (Font Squirrel provide a great resource for doing this). This way your fonts will wait before the CSS has loaded before revealing themselves.
Create a class that hides elements. Add that class to the elements that you want to hide initially. Remove the class after you've run the javascript that you want executed. Something like the following should help you.
.js-needed
{
display: none;
}
//Add this line after you've run the code you want executed
$(".js-needed").each(function() { $(this).removeClass(".js-needed"); } );
<div class="js-needed">Stuff to hide initially</div>

Progressive enhancement - not hiding elements with CSS

I often find myself showing/hiding elements with jQuery, for example a simple tabbed content area where the first tab is visible and the others are not until they are displayed with the javascript. I know it's not good practice to hide the initially hidden ones using CSS (display: none) and then showing the correct ones with JS as non-JS users will never see a thing. So by default I show all and then hide the relevant ones with JS.
In doing this though, the hidden elements will load and then only hide when document is ready. How can I stop this happening? Is there a way of doing this in a way that will degrade gracefully but also not have elements appearing whilst loading, and then promptly disappearing as this looks a bit shoddy.
Unfortunately, the way that Javascript works, this doesn't seem to be possible. There will always be a fraction of a second between the first rendered frame and by the time the JavaScript to hide the element gets executed I was wrong about that, jQuery seems to be able to do that. So, CSS is the best means for this. Luckily, you can add an alternate CSS stylesheet within an infamous <noscript> tag:
<style type="text/css">
#jquery-thing {
display: none;
}
</style>
<noscript>
<style type="text/css">
#jquery-thing {
display: block !important;
}
</style>
</noscript>
Here's the JSFiddle link:
http://jsfiddle.net/kylewlacy/dbWuc/
a few thoughts...
If you don't mind jQuery being littered all over the page as opposed to being all in a separate file, you can call $('#divToHide').hide(); immediately after the element appears. Not very good practice though. Although it depends on the use case, if you are largely a designer/themer creating a 5 page brochure site, you should choose what is right for you!
Or if you're a bit more of a techie, you might like to mess around with .live()/.livequery() and catch the element's insertion with JS and hide is straight away. See this post Is there a jquery event that fires when a new node is inserted into the dom?

How do I prevent CSS interference in an injected piece of HTML?

I'm currently developing a Safari extension that uses an injected script to further inject some HTML into the current webpage, as well as injecting some other scripts to make it work. This is all working fine, but the issue is that the HTML that is injected gets affected by CSS stylesheets that the webpage has already imported. For example, the HTML looks perfect on Google.com (which has relatively little CSS styling), but awful on StackOverflow.com (which styles buttons etc).
jQuery is injected into the webpage at the time of this HTML being displayed, so I have that available. I've tried all kinds of things, including walking through all of the elements and calling removeClass() on each of them, to no avail. I've also tried to add "CSS reset" classes, etc, but nothing seems to be working.
What's the best way to go around preventing the CSS from interfering with my HTML?
You can't prevent that from happen. However, you can override the CSS rules. Give your main element a unique id (which really should be unique by obfustation, like "yourapplicationname_mainelement_name" or something), then override all possible styles that might give strange effects on your html.
Your plugin:
<div id="yourapplicationname_mainelement_name">
<p>My paragraph that must not be styled</p>
</div>
Your css:
#yourapplicationname_mainelement_name p {
display: block;
color: black;
background: white;
position: relative;
... and so on ...
}
As your css style rules are the most specific, given your id, they will override any settings present on the page where your html is injected.
Further... It might be hard to see what rules are the most important. You can use firebug or similar to understand which is overriding another. You'll have a hard time without it when developing your application.
that's a tough one. two options as I see it.
You could set a wrapping div around all your content and prefix all your css with that. example:
<body>
<div class='wrappingDiv'>
...
</div>
</body>
stylesheet:
.wrappingDiv * {}
Then when you inject jquery use that to close off the initial wrapping div before your content and to wrap any following content in the another wrapping div.
Issues:
Only possible if you are injecting
other site content onto your own
site.
This could get complicated
depending on where you are injecting
html.
The other option is to load a resetting stylesheet that targets your injected html specifically. In this case only your injected html would be wrapped but you'd need a css file that reset all attributes for all tags to their default before you add your own styles. No real issues here, just not very elegant...
Another way would be to use an element that doesn't inherit stylesheet like an iframe, but that comes with its own issues...
i have seen on different plugins that they put the code inside a iframe and they use JS to interact with the rest of the page, so you can not change the css inside.
Also i have seen that when injecting html code,people sets the style of the plugin content using the "style" attribute inside the tags so the browser will give priority to the css inside the style attribute and not the css file. The idea is to override the css,usually with the "!important" clause. But you might have some problems on different browsers
EDIT i forgot to say that my answer is on the case that you inject the code on someone's else page where you cannot control directly the css

Shouldn't we use <noscript> element?

I found some good cons here:
The noscript element only detects whether the browser has JavaScript enabled or not. If JavaScript is disabled in the Firewall rather than in the browser then the JavaScript will not run and the content of the noscript element will not be displayed.
Many scripts are dependent on a specific feature or features of the language being supported in order for them to be able to run (for example document.getElementById). Where the required features are not supported the JavaScript is unable to run but since JavaScript itself is supported the noscript content will not be displayed.
The most useful place to use the noscript element is in the head of the page where it would be able to selectively determine what stylesheet and meta elements get applied to the page as the page is loading rather than having to wait until the page is loaded. Unfortunately the noscript element is only valid within the body of the page and so cannot be used in the head.
The noscript element is a block level element and therefore can only be used to display entire blocks of content when JavaScript is disabled. It cannot be used inline.
Ideally, web pages should use HTML for the content, CSS for the appearance, and JavaScript for the behavior. Using the noscript element is applying a behavior from within the HTML rather than applying it from JavaScript.
Source: http://javascript.about.com/od/reference/a/noscriptnomore.htm
I very much agree on last point. Is there a way to make and add an external <noscript> file? Should we place <noscript> in the <head>?
It's better to have the default be non-javascript, and then let a javascript code overwrite with a javascript enabled page. Doesn't have to be much. Can just be a display:none; block, which is then set to display:block; by javascript, and vice versa for the non-js page.
After pondering for many days and changing my code back and forth, I think I have clearer picture now and would like to share my two cents worth on the subject before I forget.
<div id='noscript'>show non-js content</div>
<script>document.getElementById('noscript').style.display='none';</script>
<script id='required script'>show js content</script>
vs
<noscript>show non-js content</noscript>
<script id='required script'>//show js content</script>
Depending on the situation, there are three cases for consideration:
Case 1 - If required script is inline
JavaScript disabled
Content in <noscript> element appears immediately, non-js content is
shown
Content in <div> element appears immediately, non-js content is shown
JavaScript enabled
Content in <noscript> element does not appear at all, js content shown
Content in <div> element may momentarily appear before being hidden, js
content shown
For this case, using <noscript> element is advantageous.
Case 2 - If required script is from external (third-party) source, but hiding of <div> element is done with inline script
JavaScript disabled
Content in <noscript> element appears immediately, non-js content is
shown
Content in <div> element appears immediately, non-js content is shown
JavaScript enabled but required script is blocked
Content in <noscript> element does not appear at all, nothing is shown!
Content in <div> element may momentarily appear before being hidden, nothing is shown!
JavaScript enabled and required script is received
Content in <noscript> element does not appear at all, js content shown
Content in <div> element may momentarily appear before being hidden, js
content shown
For this case, using <noscript> element is advantageous.
Case 3 - If required script hides the <div> element
JavaScript disabled
Content in <noscript> element appears immediately, non-js content is
shown
Content in <div> element appears immediately, non-js content is shown
JavaScript enabled but required script is blocked
Content in <noscript> element does not appear at all, nothing is shown!
Content in <div> element appears, non-js content is shown
JavaScript enabled and required script is received
Content in <noscript> element does not appear at all, js content shown
Content in <div> element may momentarily appear before being hidden, js
content shown
For this case, using <div> element is advantageous.
In summary
Use <noscript> element if rendering of the HTML content depends on third-party scripts or if the required script is inline. Else, use <div> element and make sure that the required script contains:
document.getElementById('noscript').style.display='none';
Although Tor Valamo has an elegant answer to this problem, there is an issue which may cause you to opt out of using this technique.
The problem is (usually) IE. It has the tendency to load and execute the JS a bit slower than other browsers causing it to sometimes flash the "Please Enable Your Javascript" div for a split second before it then loads the JS and hides the div.
It is annoying and to get around this you can implement the "classic". <noscript> redirect approach.
<head>
<noscript><meta http-equiv="refresh" content="0; URL=/NO_SCRIPT_URL/ROUTE_HERE"/></noscript>
</head>
This is the most solid technique that I've come across with regards to this little nasty.
One useful application for noscript that I've seen is for a progressively-enhanced async loading of heavy content (especially "below the fold"). Big images, iframes, etc. can be wrapped in noscript in the HTML source, and then the unwrapped elements can be appended to the page using JavaScript after the DOM is ready. This unblocks the page and can make for a much quicker initial loading experience, especially if your interface relies on JS/JQ interactions applied after the document is ready (2 seconds vs. 6 seconds for a portfolio page I consulted on).
These days it seems almost every browser runs Javascript, but you can never know who is going to be accessing your site. These days even screen readers and web crawlers use Javascript, and sometimes make AJAX requests if they have to.
That said, if you're going to fall back to no-Javascript, there is a much better way than a <noscript> tag. Simply do this in the HEAD of your document:
<script type="text/javascript">
document.getElementsByTagName('html')[0].className += ' Q_js'; // better than noscript
</script>
With this technique, you can easily refer to the Q_js class in your CSS to hide things. With the <noscript> tag, the best you can hope for is to include an additional CSS file to override previous CSS. This becomes important when some elements with static content are supposed to be hidden right away (not flicker) until Javascript can make them more dynamic.
In short, the technique I suggested addresses all your cons 1-5, and I believe it's strictly better than using <noscript>.
In the (hopefully near) future you will be able to use css #media scripting:
#media (scripting: none) {
/* styles for when JS is disabled */
}
I create a full height, full width, position:fixed div in all pages with some id .
<div id='noscript_div' style='position:fixed;z-index:20000000;height:100%;width:100%;line-height:100%;'>enable JS buddy</div>
$('#noscript_div').hide();
$(document).ready(function(event){
});
I am not an expert . This worked for me .
I am sorry but, this case will suit only if you want the user to have his javascript enabled always
the simple ideea is in this times your website may adapt to no javascript usage on slow devices using noscript tag like an entity for the entire content of your website**(your html should be prepared to no javascript and all controls must work also if javascript is off,users using basic html controls shoul be able to do everything they done before when javascript was active.So <noscript></noscript> can be the dynamic switch to the same content in other way with the same results=solving the problem wich is the reason the users open your url).**You can see is no matter javascript is or not present ,the website's functionality can be "the same" in any cases js enabled / disabled.On chinese slow devices eg:Samsung neo mini phone this method can run an website without any delays on low internet traffic..
try to run this auto double functionallity website if js is on/off cases:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><HTML>
<HEAD>
<TITLE>noscript can change the Internet forever</TITLE>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
</HEAD>
<BODY>
<SCRIPT LANGUAGE="JavaScript">
<!--
$(document).ready(function(){
$('noscript').replaceWith(function() {
return this.textContent || this.innerText;
});
$("p#javascripton").css("background-color", "yellow");
$("p").click(function(){
$(this).hide();
});
});
//-->
</SCRIPT>
<noscript>
<p>
Noscript's usage today can be logical for <p id="javascripton">eg pc/laptop/high quality tablets usage the complete website with all features:images high resolution,javascript<br><h1>OR without javascript so no high resolutions images inserted with a jquery automated script generated from some php+javascript scripts so have usage for 80% mobile application cause almost are from China ,so low quality products=low cpu,low ram :IN THIS CASE SOMEONE CAN THINK TO SWITCH HIS PHONE TO NO JAVASCRIPT USAGE SO IF ANY PROGRAMMER CAN ADAPT AN ENTIRELY APPLICATION TO THE METHOD I USED IN THIS EXAMPLE AUTOMATED HIS BROWSER IS ADAPT FOR ANY RANDOM ACTION ABOUT THE USER CHOISE(YOU UNDERSTAND "TO USE OR NOT JAVASCRIPT") SO HIS CHINESE PHONE CAN BE APROXIMATELLY APROACH LIKE QUALITY OF SPEED EXECUTION THE OTHERS PC/LAPTOPS/TABLETS QUALITY PRODUCTS.<BR><BR>This stupid example is the best example how no script tag can change the quality of services on this planet ,boost the speed of the internet connection and stops unnecessary use of A LOT OF INTERNET TRAFFIC on slow devices..a simple tag can change the entirely dynamic of programmer's views so entirely Planet's beneficts</h1><p> <br>
run this code in two instances :<br>with browser javascript enable <br>and without(browser's javascript disable or eg a firefox plugin noscript states on/off)
</p>
</noscript>
</BODY></HTML>
and to say more on this .. right noscript was invented to work like a trigger when js is disabled but you can work around this feature to change the course of internet functionality about how is now ,to change it's dynamics....
Like all things, use the right tool for the job.
If you are using Google Maps API, you have a static image via tag and that gets replaced with dynamic JS map. Google have recently started charging for everything thus with the above example it's going to cost you twice, once for static and once for dynamic. The static map is only relevant if JS is disabled. Therefore to save double paying it seems to me the best solution is to wrap the tag for the static map in a tag.

Hiding a div using JQuery

I want to hide a div using Javascript, as soon as the page gets loaded in the browser. I am able to do that, if i use the following code :
document.getElementById("div_id").style.display='none';
But, when i try to do the same thing using JQuery,i notice that the div is visible for a couple of seconds after page loads,and then it becomes hidden. The JQuery code i use is
$(document).ready(function() {
$("#div_id").css('display','none');
});
The same thing happens, if i use $("#div_id").hide(); Is this because im using a library,which would slow down the process a bit,instead of directly using document.getElementById ? . Any way to fix this ?
Thank You.
There's an easy solution to this. Set up a CSS class as follows
.js #div_id { display: none; }
Then have the following jQuery
$('html').addClass('js');
$(document).ready(function() {
/* normal code to run when DOM has loaded here */
});
the <div> will be hidden immediately (no flashes) if users have JavaScript enabled and won't be if they don't (which circumvents possible graceful degradation problems as meder points out in his option c).
This works because when can immediately access the <html> element when the page starts to load.
The reason why document.getElementById("div_id").style.display='none'; is probably working is because you have it in the <body> after the element and therefore the script does not wait for the whole DOM to be loaded before executing.
You could either
a) insert a script element directly after the element to hide it with jQuery:
b) have inconsistent Javascript by directly using DOM methods like your first code snippet
c) hide it with CSS with the disadvantage that for CSS enabled non-JS users they wouldn't be able to see anything
I would choose between A and C, though I'm not sure exactly what you're hiding.
A:
<div id="foo"></div>
<script>$('#foo').hide()</script>
C:
div#foo { display:none; }
First, use $("#div_id").hide();. It's more idiomatic for jQuery.
Second, it's because you're using $(document).ready. Usually, that event doesn't fire until the DOM is available for use. However, because of the way bindReady() is implemented, it's possible on some browsers for this event to be equivalent to the onload event, which won't fire until everything is loaded. Unfortunately, the only way that I know of to get around this (that doesn't cause problems for disabled users who can't use JavaScript because of a screen reader) is to set a short timeout (say 50ms) and repeatedly check for the existence of $("#div_id") while the page is loading. This is a horrible hack, and I hesitate to recommend it, but it should work. That said, you're almost better off just accepting the flash of content, knowing that most users won't see it.
I think a better option would be to style the div so that it is hidden when the page is written, without any javascript.
Then, whenever you are ready to show it again, use javascript to unhide it:
$('#someId').show();
It might be cause by the way you include the scripts. The browser has to download them before they are run. So if you have a lot of js files this can cause this problem.
I think the reason is that the DOM loads progressively and the $(document).ready event is waiting for the DOM to be fully loaded before executing.
If you really want the element to be invisible when the page loads, can you define that style in your CSS instead?
I haven't tried this, but if you still want the div to be visible for non-Javascript users then I think you could do something like this:
<noscript>
<style type="text/css">
#elementid {display: block !important;}
</style>
</noscript>
More likely it's because you are waiting until the document is ready to hide it. This seems more like a job for server side script if you want it hidden by default.

Categories