I need to measure the navigation of my site to determine the space available for a feature I am building. I recently added a custom font...
The trouble is that I measure the navigation before the new font is loaded. The new font then loads altering the width of the navigation. I am then left with an incorrect width.
Is there a way I can determine when the font has loaded with JavaScript. I am using CSS to load the font.
I assume you are waiting on $(document).load before running your jquery? This just waits for the DOM to become accessible. If you want to wait until the entire webpage (and associated files) are ready, use $(window).load:
$(window).bind("load", function() {
//nav resize code here
});
I wouldn't wrap your entire code in this, just the part that is dependent on the fonts.
Related
My purpose is to achieve something like what you can do with CSS links, when you add media attribute and you can disable those CSS for a resolution of less than n pixels and still load them and use them.
What I'm trying to do is adapt a Joomla website into a mobile one using jQuery and Bootstrap, but some plugins call their own scripts and CSS files when they are inserted, and I can't change this behaviour, nor delete the scripts because client doesn´t want desktop layout to change. So for CSS i did this:
$(document).ready(function({
$('body').find('link').attr('media', 'screen and (min-width:969px)');
}));
This actually works perfect for CSS because it still loads, but doesn´t interfere with mobile layout that calls Bootstrap. So what comes next its try to do the same for scripts, I have tried this
$(document).ready(function({
$('body').find('script').each(function(){
var screen = parseInt($(window).width());
if(screen>==969){
$(this).removeAttr('src');
}
});
}));
But it's not working, and this solution won't work either if screen size change, so am I missing something, or what could be the best approach? My intention is to target the body since here is where this inserted tags could appear. If I remove all script tags content for dekstop would not display properly. Is there something as the media attribute for script tags?
For the javascript you can use the mq function of Modernizr, this allows for you to programmatically check if the current browser window state matches a media query.
First you have to load modernizr.js
For example:
small = Modernizr.mq('only all and (max-width: 1200px)');
...
if(small){
...
}
I've got a page in my web app that dynamically loads a view containing html and some javascript. The javascript basically renders a chart into the view that's been retrieved. The issue is that the chart library I'm using (flot) requires that the container it is being rendered into has a width and height.
When the javascript is being executed, the CSS rules haven't been applied to the container and it doesn't have a size. How can I wait until the CSS has been applied before the javascript runs?
In JQuery, you can do
$(window).load(function()
{
//code fires after the layout has been calculated/rendered
});
The doesn't work if you have javascript changing CSS after the page has already been loaded tho...so be sure any JS changing CSS happens before anything else you're about to do
Turns out I was simply being a complete idiot!
I was passing the container ID to flot without the "#" so it wasn't finding a container at all. The CSS rules have been applied when the view is returned and it's now working fine :)
I am looking for a way to modify some text inside the HTML before it is being parsed by the browser.
More precisely, I would like to remove some tags from the HTML so the image resources would not be fetched by the browser, only when I am ready I could insert these tag back to have them loaded.
Is it possible to do that via some JS/Jquery or CSS, if so, how?
the motivation here is to be able to block the loading of some resources on a page and have them loaded only when needed according to some logic. this needs to be done by some kind of scripting added to the page
Because you're doing this in JavaScript the HTML is already being processed when it comes to launch your <script> tags.
You could move your <script> tags into the <head> from the <body>, or move it to the very beginning of the body. However the problem here is that you'll have to wait for your elements to actually be created in the DOM before you can work with them.
You could use something like setTimeout() or similar and continually look for them until you find them, but there's still going to be a slight delay between them being created and your script finding them, at which point they might already start to load.
The only surefire way is to process the markup server side long before it gets to the browser.
My answer here possibly could be of use, if you can place noscript tags in key places in your markup prior to parsing/evaluation:
Client-Side Dynamic Removal of <script> Tags in <head>
This method—for javascript-enabled agents—would delay the rendering of the entire page however, or at least the regions that you needed to affect.
basic generalised theory
Wrapper your body or specific region with a noscript tag identified with either a class or id. Place some javascript to execute directly after the close noscript that grabs the tag and reads the html contents as a string. At this point you could modify the html string however you like and then re-inject it back into the DOM replacing the noscript tag.
more specific implementation
If you know before-hand which resources you need to postpone—say all your images—you could wrap each image in-question with a noscript tag. Then trigger off some JavaScript that grabs all noscripts and rewrites the contained image html to use a placeholder or lower quality version of the image. At the same time you could set up event listeners or timeouts that inject the actual images when the time is right.
The Lazy Load Plugin for jQuery is maybe what you are looking for. It delays loading of images in long web pages.
You can use any jQuery event such as click or mouseover. You can also use your own custom events such as foobar. Default is to wait until user scrolls down and image appears on the window.
Beside all the It is also possible to delay loading of images. Following code waits for page to finish loading (not only HTML but also any visible images). Five seconds after page is finished images are loaded automatically.
$(function() {
$("img:below-the-fold").lazyload({
event : "sporty"
});
});
$(window).bind("load", function() {
var timeout = setTimeout(function() {
$("img.lazy").trigger("sporty");
}, 5000);
});
Check the delayed loading demo.
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>
We have some JavaScript code that resizes <div/> elements (adjusts height/width/padding/margin etc.) based on the dimensions of a parent <div/> element, specifically the height and width of the parent we use in the calculation. The parent div height and width is defined in a external CSS file, and <link> is used to include the stylesheet, in the <head> section of the page. All stylesheets are included before javascripts. The JavaScript resize code is fired inside of a jQuery document ready event using the standard $(function() {}). All stylesheets and javascripts automatically have timestamps appended to them (Rails application) to ensure they are not cached (in development).
In Firefox 3.6 the resizing works every time. However in Safari 5, occasionally the resizing fails, because the parent height/width is incorrect, which appears to be because the stylesheet has not loaded before the JavaScript. Frustratingly, this happens every few times, and is different depending on the browser/machine load. I can put the resizing code inside a setTimeout() and delay it by 1 second or so and get it to work reliably, but this is not a releasable solution because it is too slow, and still varies by machine. Ideally there would be a way to guarantee the stylesheet is downloaded, then fire the JS resize code.
First of all, is this a bad design, to have JS resizing based on CSS loaded from an external stylesheet? I'm considering trying to place the height and width inline so it is rendered from the server, but this requires significant app code change and tighter coupling to the UI, and I'd like to avoid inline style if possible. Is there a webkit event by chance when stylesheets are loaded? I don't think there is. Any suggestions on a method other than a timeout to ensure all stylesheets are loaded before firing JavaScript? Anyone else experienced differences in stylesheet load order/timing between Webkit and other browsers and have a solution to share? I could use some fresh thinking on this problem.
Note: in general for images, we use the load ($(thing).load(fn(){})) event on images to ensure they are loaded before applying any JavaScript to them. That would be a good pattern to follow if such a thing existed. Thanks!
Co-worker (#johnreilly) found a couple solutions, one polls the document.readyState property when the browser is Safari looking for a value of complete.
Get the real width and height of an image with JavaScript? (in Safari/Chrome)
Another creates a cssLoaded custom event and uses :after pseudo-selector to avoid polling. http://stilbuero.de/demo/cssloaded/
So the first solution is acceptable. I'm putting it in the main javascript file and using $.trigger() to emit a custom event to our handlers that depend on Webkit having fully downloaded the stylesheets.