I want to prevent an specific background-image being displayed on a page, possibly using jquery. However, the page and DOM is loaded before the JS is activated.
What I want to do is the following:
.pagelayout-login #page{
background: none;
}
I have tried the same in JQuery using:
$(document).ready(function(){
$(".pagelayout-login #page").css("background","none");
});
However, both modify the stylesheet after the image has been loaded and displayed.
If I add "run_at : "document_start" inside my content scripts, the CSS get's overridden by the page's CSS.
Is there a way to prevent the background from being displayed before it starts loading?
you can add the CSS at the beginning :
chrome.tabs.insertCSS(tab.id, {code:'my css code', allFrames:false, runAt:"document_start"});
or add a script at the end like this :
chrome.tabs.executeScript(tab.id, {code:'my script code', allFrames:false, runAt:"document_end"});
with the CSS, you need to be the first, because it's a "Cascading Style".
with the script, it must be the last change.
You can try to add !important to your CSS.
I'd think this would be a lot easier the moment you remove the $(document).ready, everything inside that function runs after the page has completed loading.
Since this is in a Chrome extension, don't be afraid to use !important to ensure that your CSS overrides the page's CSS even if you "run_at : "document_start":
.pagelayout-login #page{
background: none !important;
}
This may or may not prevent the image from loading since it's still being referenced by the page's CSS, but it will at least prevent it from displaying right away. You will need to conduct your own tests to determine if Chrome will still attempt to request the image during page load in spite of this.
Related
I am building an AJAX-based website where all of website content is being loaded through AJAX.
Some pages have CSS that's being loaded along with content (code follows). Once the HTML and CSS is loaded I run a few scripts to change some image positions, alter width, and so on.
The problem is that sometimes my javascript gets executed before CSS rules get applied. For example: if my div width should be 200px according to the css, sometimes javascript reads it as 1000px, so I get wrong calculations.
My research has not yielded a cross-browser solution to detect not only loaded images but loaded CSS and everything else.
I use jQuery's AJAX function to get the desired HTML (this part is working fine). After I get the HTML I apply it with jQuery's html function.
Once that's done I use this code to load required css:
css = document.createElement('link');
css.rel = 'stylesheet';
css.type = 'text/css';
css.media = "all";
css.href = url;
document.getElementsByTagName("head")[0].appendChild(css);
I could use a timeout function, but it would just be blind guessing, and I want to make sure my script runs when it needs to run. Any sugguestions?
EDIT I have included this image to make explanation clearer
Never tried before, but what about Stylesheet load events? In case IE won't fired the onload event, and you need to support it, onreadystatechange should works.
I'm glad to see I'm not the only one who has this problem.
I have some JavaScript which needs to be run AFTER the CSS styles are applied to the DOM.
I think what ZER0 suggested is a good solution, but I could not use the OnLoad event on my CSS <link> tag because I load a single concatenated/minified JS file at the end of the document, while my concatenated/minified CSS is at the top of the document.
My solution:
Put the essential CSS styles that the JavaScript depends on directly on the DOM using <style> tags.
This way, the styles get applied immediately when the DOM gets loaded. By the time JS is running, the DOM has the essential styles applied.
I think that you are over-complicating the problem. If you set all of your CSS up to only react to a certain parent class--eg: if you dynamically load the about page--all the CSS should look like .about .example {} .about h2 {} etc. The same would go for the contact page .contact img {}
Now, unless your CSS file is absolutely massive, if you include the one file at the top, you can pretty much guarantee that the CSS will be applied.
I have done a bit of a web development faux pas by not starting with a functioning page and then building js functionality on top. The site I am redeveloping is an old site which has lots of pretty jquery animations.
I have gone to great trouble to ensure all page loads can be handled with or without ajax but I have just realised this is entirely pointless since the initial page load produces several elements which load with properties of display:none; or opacity:0; and are animated to be visible on doc ready
I would very much like to rectify this but there are several reasons I did it in the first place:
1: to hide a flash of unstyled menu before a jquery plugin kicks in. (I will replace this with a non js menu and animate into the jquery menu to solve this)
2: The other reason is that I like the initial animation on page load and would ideally like to keep it. But this presents a problem since I would like to have the bulk of the page invisible for js users and visible for non js users on load but how can I ensure that my elements css properties are changed BEFORE the page is rendered - I have tried doing this with jquery but by the time the jquery library has loaded (without caching) my page has already rendered so the content is flashed up before being hidden and animated back in?
This block will be visible only for users with JS turned off.
<noscript>html code here</noscript>
You can add some styles like this:
<noscript>
<style>
#content{
background: red;
}
</style>
</noscript>
You can add the following in your <head>:
<script>document.documentElement.className+='js'</script>
Then you can style javascript-enabled browsers differently using the js class on the html element, f.ex:
html .animate{opacity:1} /* all browsers */
html.js .animate{opacity:0} /* js-enabled browsers */
The class is added already in the head, so there is no flicker in the rest of the DOM.
You can also use the noscript tag, but personally I think this is cleaner because you can administrate the styles in a single stylesheet.
I am using the Google Webfont Loader to get my webfonts loaded with a callback and it is working fine.
Although, when a couple of components: Google +1 button, Twitter Search Widget and the Add This button is loaded, they add a new stylesheet to the DOM and makes the browser render the site again. This is causing the font-face to disappear and then show for each new stylesheet added to the dom.
I could hide the font entirely until the components are loaded but they tend to be pretty slow so that would leave me with a pretty bad user experience. About 1 sec of a headline-less site.
Andy tips on how to force font-face to not redraw or how to block dynamically loaded CSS from within Google, Twitter and FBs embed scripts?
Update: Demo here http://kristoferforsell.com/dev/fontexample/
This is currently an inherent issue with browsers and the #font-face property. The blink occurs when the font is loaded and the page updates to reflect the font. If you wish to remove the "blink" entirely, the only sure fire way is to include the font as a data URI in the style sheet. Of course, using the standard "safe" fonts will also remove the blink.
Data URIs allow you to actually embed the code for the font in the stylesheet so there's no blink when the page refreshes to show the desired font. Using data URIs, will obviously increase the file size (kb) of any style sheet.
An online converter to get base64 code can be found here
Usage for #font-face would be like so.....
#font-face {
font-family: "My Font";
src: url("data:font/opentype;base64,[ the base64 code here ]");
}
Not sure if it would fix your issue but you could use css to set the visibility of the elements to hidden until the font is loaded. Google's API provides wf-loading and wf-active classes which are added to the body to address this issue.
I always set up a separate stylesheet just for the #font-face rule, and within that put in the following rules, where replace is the class of the element that's being replaced, for you that would just be the p tag.
.wf-loading .replace { visibility: hidden;}
Yours would be
.wf-loading p { visibility: hidden;}
Then as soon as the webfont is loaded, JS puts the wf-active class on the body, and your text shows up. Let me know how that goes and if you have any issues then just drop me a line. It might also be worth doing some searching for "flash of unstyled content" or "flash of unstyled text" as this is a well known and well documented bug.
I can suggest a simple and dirty trick I have used myself to solve issues like this. If you implement this, from the user's side the effect will be that the entire page will load at once (with the correct Web Fonts), but after a delay. Once loaded, nothing will flicker or change.
Wrap your entire page contents in a div and set its visibility to hidden. Then use js to turn on the visibility once the whole page (stylesheets and all) is loaded.
Here's the code:
<head>
<script>
function show()
{document.getElementById('wrapper').style.visibility='visible';}
</script>
</head>
<body onload="show()">
<div id="wrapper">
...your entire page contents...
</div>
</body>
The onload ensures that the visibility is switched on only after the entire body has loaded. Although I haven't used Web Fonts, I use this trick to fade in the entire contents of this website with no changing or updating afterwards. But yes, there will be a delay before the entire page comes into view.
EDIT: I added Google Web Fonts to the site I linked. Still works fine. No font-face flickering.
This is a shot in the dark, as I've not tested it:
Could you create another html page with only those social networking buttons, and then load that into an iframe? Then only set the src to the iframe once the document is fully loaded, so it doesn't hold anything up.
In html:
<iframe id="socialMedia"></iframe>
In script:
$(document).ready(function() {
$('#socialMedia').src = "http://mysite.com/mysocialmediastrip.html";
});
Where mysocialmediastrip.html contains all the social media buttons. Setting the src will cause that iframe to reload and pull in that content, but IIRC, the rest of the page will be left alone -- all of the button rendering will have been done in mysocialmediastrip.html, not in your main page.
I totally understand what you are saying about the delay process, waiting while window loads before you actually show your goods. Abhranil provided a good solution but you can take his solution further. You can use jQuery's ajax to load your specific page content that's using the special font type. Why? because ajax comes with a special function called beforeSend(). Within the beforeSend function(), you can load a very cool gift animation that will display on your screen, before your main content is ready to viewed.
Use that moment to show some creativity towards your audience, before the main event!
The best and most simple answer is adding font-display: block when specifying a font face
#font-face {
font-display: block; /* Fix flickering */
}
You should also preload the font in the html file
<head>
<link rel="preload" as="font" href="/path_to_your_font.ttf">
<-- repeat for all typeface -->
</head>
I'm working on a project where there's quite a lot of jQuery going on. So when I go to the page, I can see the jQuery running (e.g. $.button() elements on the page still appear as normal html elements before jQueryUI is loaded :S) so initially it looks all ugly THEN, once all the JS is loaded and executed, it looks "nice".
It's not just a case of preloading images or whatever, I want to RUN the jQuery code, but "hide" it from visitors so that once the page is opened, it looks "nice" straight away OR displays a black screen saying "Loading..." until the jQuery has finished running.
Take a look here: http://www.filamentgroup.com/ , though I'm not sure that actually runs the site's javascript before displaying it, but it shows the basic idea of having a dark screen saying "Loading...".. I suspect that's what happens in large web apps such as SlideRocket though it does use flash... :S
You answered the question yourself. Have some kind of loading screen that hides the page until all of the jQuery is run.
Try something like the following.
This goes at the top of your page:
<div id="loadingMask" style="width: 100%; height: 100%; position: fixed; background: #fff;">Loading...</div>
Here's your jQuery:
$(document).ready( function() {
/*
* ... all of your jQuery ...
*/
// At the bottom of your jQuery code, put this:
$('#loadingMask').fadeOut();
});
Wrap all of your jQuery that you want "preloaded" into this :
$(window).load(function() {
//Your jQuery here
});
or alternatively, not all of your jQuery code inside of that wrapper. Rather, put your jQuery DOM changes into a
$(document).ready(function(){
//jQuery
}))
and then have a wrapper for all your site content.
<div id="everything-wrapper">
<!-- put your body here -->
</div>
and set the display to none in your CSS
#everything-wrapper {
display : none;
}
and then with the window load like earlier
$(window).load(function() {
$("#everything-wrapper").show();
// or
$("#everything-wrapper").fadeIn("fast");
// to be fancy with it
});
I was having a similar issue with an artifact popping up briefly during page loads in IE8. The solution I used was to change the visibility of the container to hidden at line 1 of the css. Then showed the element at the end of the jquery file. If the css and jquery start arguing, the element isn't shown until the argument is resolved.
I would have a overlay as part of your static CSS and HTML, then when JQuery loads via
$(document).ready() you can hide the overlay
The answer by Christopher is most likely the way FilamentGroup do it. You can have javascript "preloaded", it loads inline with the rest of the page, and due to it usually being larger than the rest of the page takes longer to download. You can't make javascript load first, that's not the way it works.
However, the principle to make it work is to "hide" your page from view in CSS (or with inline styles as the CSS will still have to load) then once everything is ready in javascript show it all again. If you notice there is a gap between the page displaying (nothing) and the javascript loading showing on FilamentGroup. That is because they hide the page, the javascript loader loads, then once the rest of the javascript has finished it hides the loader and shows the page.
Dude, I did you up a sample. I hope you likes. I use something like this on my own site.
http://jsfiddle.net/jMVVf/
I'm learning Javascript and CSS and have run into an issue where my CSS styles aren't being applied to markup that I'm dynamically generated from XML and writing to document after the page has loaded. I can only assume that the styles aren't being applied because I'm modifying the document after it's already been loaded. Is this correct? If this isn't the case, do you have any ideas as to why the styles aren't being applied?
This javascript code...
$(function()
{
//Dynamically generate markup
strMarkup = GenerateMarkupFromXML();
//Display the dynamically generated markup
document.write(strMarkup);
});
dynamically generates this simple markup...
<div id="accordion"><h3>Title1</h3><h3>Title2</h3></div>
but these styles don't ever seem to be applied and the <h3> tags just get displayed with the default browser style...
h3
{
background-color:#ccc;
color:#003300;
font-size:1.1em;
}
I should also note that when I paste the dynamically generated markup directly into the body, the styles are applied correctly.
Thanks in advance for all your help!
Yes... the styles will be applied to any dynamically added markup.
The document.write() portion of your code may be causing problems here. In general, you should only use document.write() inline as the document is loaded and parsed. If you call it on DomReady as you seem to be doing it will overwrite your entire page, which I guess is what's causing the problem. I haven't tested though.
I'm not that familiar with jQuery, but instead of the document.write() line try doing something along the lines of (untested):
$('body').append('<div id="accordion"><h3>Title1/h3><h3>Title2</h3></div>');
Yes, css applied automatically. Your example don't work because document.write is evil )
It rewrites whole document with your custom styles, I suggest. If you want to use document.write call it in appropriate section of document, not in head. Example:
<head>
<style>
h3
{
background-color:#ccc;
color:#003300;
font-size:1.1em;
}
</style>
</head>
<body>
<script>
document.write('<div id="accordion"><h3>Title1</h3><h3>Title2</h3></div>');
</script>
</body>
Yes, CSS styles are applied to markup that is added after the page loads.
It could be that you aren't actually generating the same code that you think you are. Try selecting the generated code and doing "View Selection Source" in Firefox. This shows you the generated source (i.e. not just the static content that was served when the page was loaded).
Edit
I think there is a problem with using document.write() in the document ready function.. seems to be causing some kind of infinite loop (for me in Firefox, the browser keeps spinning the loading icon on the tab, even though the file is on my local machine). The $('body').append(strMarkup); solution posted by Andy works, though, as does $('body').html(strMarkup);;