Is it possible to detect - using jQuery or pure DOM manipulation / events - when an image that was injected into the document has fully loaded? For example, a script needs to replace one image with another. If it just changes the src attribute, the user will see an image disappear briefly (or not so briefly, depending on their connection). So, a better option would be to create a new image element in some hidden place (or, if cross-platformly possible, out of DOM entirely) and switch images only when the new one is ready. Can this be done?
EDIT: It might be a separate question, but still... Is there also a way to detect when an image has failed to load?
You can use image.onload = function(){<...>};
Image is the actual image you want to get the load of.
<img src='...' id='image'>
In order to check if the image finished loading do the following->
document.getElementById('image').onload = function(){<...>}
or
document.getElementById('image').addEventListener('load',function(){<...>},false);
If you want to check if the image failed to load do this->
document.getElementById('image').onerror = function(){<...>}
or
document.getElementById('image').addEventListener('error',function(){<...>},false);
Note
.addEventListener method won't work in IE8. If you are planning on supporting it I can edit my answer.
yes you can do that by using the .load() event.
like,
$('#img1').load(function(){ alert('loaded'); });
the alert will be displayed when the resources for that particular selector has loaded fully.
The .load() event does not always work as expected and is prone to fail under different circumstances. For broadest browser support I suggest to use DeSandro's imagesLoaded (which I find to be best practice anyway): https://github.com/desandro/imagesloaded
Related
I am dynamically changing images with jQuery using $('img').attr('src','newUrl');
Doing so, the image is only displayed when entirely loaded.
My connection is slow, so I would like the image to directly display and see it getting progressively loaded, the same way images “appear” when I arrive on any page on the web (whether from top to bottom, or from blurry to sharp depending on the compression algorithm of the image).
I want to do this with javascript, jQuery, or any simpler alternative.
(I know how to display a progress bar, or a "loading…" text while the image loads, that's not what I'm looking for)
Here's a fiddle if you want to update.
I've found a way to do that, what you want. Don't use attr("src",) from jquery, remove and add the hole img element with html(), so you trigger the browser to load the image source and the browser displays the image while loading (tested in chrome).
Html:
<p><button>change image source</button></p>
<div>
<img src="http://xxxxx">
</div>
Script:
var newImg = '<img src="http://yyyyyy">';
$('button').click(function(){
$('div').html(newImg);
});
Here is your updated fiddle: http://jsfiddle.net/jxwv52u7/1/
I hope it helps.
Based on some testing I did about a year ago, I found no reliable way to get a load event when changing the .src of an image from one value to another. As such, I had to resort to loading a new image and replacing the one I had with the new one when the new image was loaded. That code has been running successfully in several hundred web sites (it's used by a slideshow) for about a year now so I know it works.
If you set the load handler BEFORE you set the .src property on a new image, you will reliably get the load event. Here's some code I wrote just earlier today for capturing the load event: jQuery: How to check when all images in an array are loaded?.
This code that attaches the event handler BEFORE settings the .src works for me in the modern browsers I've tried it in (I didn't test older browsers):
$("img").one("load", function() {
// image loaded here
}).attr("src", url);
You can see it work here:DEMO and you can test any browsers you want using that jsFiddle. Just click on the image to cause it to load a new image. It cycles through three different images (setting .src each time), loading two of them uniquely every time (never from the cache) and one from the cache in order to test both cases. It outputs a msg to the screen whenever the .load handler is called so you can see if it's called.
I'm looking for a reliable way to block image network requests with javascript. I read this: Prevent images from loading
It seems that it's a bit hit-and-miss as to whether the image request or the javascript will fire first.
Does anybody understand the order in which stuff happens? Can I tie into some sort of hook where I can run some javascript before any network requests are made? Or at least abort any existing ones.
Thanks.
Images are loaded when the src attribute is set. You can either dynamically create the image tags, or just set the src attribute when you want the image to load.
Also note that different browsers render pages in different ways. so preventing the load with javascript, is likely to work on certain browsers and not others
You can't avoid that - your browser will always try to load the images of your img tags. You will have to load the images dynamically via JavaScript.
So there's no issue with this code functionality itself. I have something like this:
<div>
<div><img id="imageToChange" src="/path/image.png" /></div>
<div id="textToChange">Text</div>
</div>
I have another part of my code, that changes the image src/text with jQuery.
function changeImage() {
$('#imageToChange').prop('src', '/path/image2.png');
$('#textToChange').html('New Text');
}
As you may expect, this works exactly as I expect it to. But with 1 quirk.
In all the main browsers (chrome/FF/IE). The image takes a long time to change.
So for example, when I call changeImage(), the text will change instantly, but the image may not change until 1-2 seconds later. (Not large images by any stretch, about ~6KB, and local)
I haven't found anyone else really complaining about it, but what I'm wondering is if there's any way to speed up the changing of the image src? Perhaps a better way to do it?
This is jquery 1.8.0 as well.
Thanks
I have seen this behavior before. The delay is caused by the image not being cached and the subsequent load time. The only solutions I know of:
Preload your images with JavaScript Image objects.
Handle the load event on the image and update the text after the image as loaded. Note jQuery lists some issues to watch out for:
Caveats of the load event when used with images
A common challenge developers attempt to solve using the .load()
shortcut is to execute a function when an image (or collection of
images) have completely loaded. There are several known caveats with
this that should be noted. These are:
It doesn't work consistently nor reliably cross-browser
It doesn't fire correctly in WebKit if the image src is set to the same src as before
It doesn't correctly bubble up the DOM tree
Can cease to fire for images that already live in the browser's cache
http://api.jquery.com/load-event/
You may want to try altering the attribute using the jquery .attr function. If I recall correctly the src tag of an image is an attribute not a property. Although both .prop and .attr do relatively the same function, to ensure consistent behavior between browsers you may want to use the .attr tag instead.
$('#imageToChange').attr('src', '/path/image2.png');
As far as the delay goes, this could be due to the size of the image. The browser has to make a GET request to the server for the image and then paint the DOM with it. If the image is large, it could cause a time lapse between when the code changes the source and when the new image is properly written to the DOM. If the image is large, you may want to consider scaling it down or optimizing it for web use.
Hope this helps.
You can pre-load the image using the Javascript Image object.
In the head of your document put
<script type="text/javascript">
img2 = new Image();
img2.src = "/path/image2.png";
</script>
when you change the src of the image you fetch another image file. it makes an HTTP request for the new image, so it needs to load before showing it. could this be it?
btw, for this reason you can pre-load the image with js. either add
<img src="path/to/image.jpg" style="display: none" />
to your html or using JS
var im = new Image(1,1);
im.src = "path/to/image.jpg";
this way the image will be cached
It's the delay of network. Try this:
<div>
<div><img id="imageToChange" src="/path/image.png" /></div>
<div id="textToChange">Text</div>
</div>
<img src='/path/image2.png' style='display:none'>
it is likely the load time of your images. if this is the case, loading the image the first time should be the only slow one. a follow up load, after changing the image to something else, would be fast.
$('#imageToChange').prop('src', '/path/image1.png');
//slow, need to fetch image
$('#imageToChange').prop('src', '/path/image2.png');
//slow, need to fetch image
$('#imageToChange').prop('src', '/path/image1.png');
//fast, it already has this image
As a solution, you could try preloading your images. Or, better yet, use css sprites.
Is it possible to do something after the dom is ready but it is not rendered(White screen)
I would like to hide the contents from user and after some operations i would like to show the final picture.
I could use "display:none" on my body tag but i am working on a huge project so i dont want to change every page.
Thanks
Here is how?
document.onload = function() {
//your codes
}
Unlike, window.onload this function runs after the DOM is loaded, so the manipulation is possible, but it does not require all the elements to be rendered.
Is it possible to do something after the dom is ready but it is not rendered
Browsers render the DOM incrementally as they parse the HTML into it. The state you describe will not happen naturally.
You can fake it such…
I could use "display:none" on my body tag but i am working on a huge project so i dont want to change every page.
If you don't want to change every page because it is too much work, then too bad. Go and set up an external stylesheet that every page uses.
If you don't want to change every page because you only want the changes to appear on certain pages, then use a more specific selector.
That said, preventing content from displaying and giving users a white screen (or even a loading screen) is just going to turn people off and drive lots of them to another site. I wouldn't recommend doing this.
if you could use JQuery this one is called when the dom is ready but the page not loaded
$(document).ready(function(){
)};
I'll contribute my own 2 cents here.
With jquery, the $("document").ready() event fires after the DOM has been fully loaded(without images, that is) to your browser, but not displayed. So I think to achieve what you want, you'll have to input some handler function inside the ".ready()" method to handle whatsoever you desire to achieve.
Is that what you were looking for?
Twitter generates me box code to insert on page: http://pastebin.com/5TgkL5vP but on slow connection it prevent page from loading. Is there any way to add "Loading..." and make it async? (I know about iframe but its awful way)
There is a solution in here;
http://od-eon.com/blogs/stefan/asynchronous-loading-twitter-widgets/
$(window).load(function(){
$.getScript('http://widgets.twimg.com/j/2/widget.js', function(){
$.getScript('/media/js/twitter.js', function(){
$('#twtr-widget-1').appendTo('#twitter_p')
})
})
})
To delay the loading of the twitter widget you could load it after your whole page is loaded. You could use the window's onload event handler to start loading the twitter widget once your page has been downloaded.
Or you could use a javascript library (like jquery) to run that code once you HTML is loaded but images and CSS and other assets are still loading: jquery's .ready() method does just that.
In case you don't want to use bare javascript (although recommended for learning) jquery (like others) does provide a .load() event that behaves just like the onload example on W3c.
In any case, with any of those two methods you could place a "loading..." text in a placeholder and then replace it with the widget once it's loaded.
You should try experimenting with both and see which one produces the best perceived results. Sometimes you want the page's content to load blazingly fast, in that case you should hold all external content from being loaded until the content is loaded (using onload or .load()), while sometimes you want everything to be loaded more or less at the same time (using .ready()).
I hope it didn't come out backwards :D.
The solution explain by od-eon.com is OK but for IE the CSS is not correctly added because it tries to add CSS in a window onload event. This event is fired asynchronously so no CSS is added.
The line $('#twtr-widget-1').appendTo('#twitter_p') is not useful.
You must not add a CSS position attribute to the div which will contain the box because nothing is displayed in this case. If you want to add this box in an absolute div you must add an empty div in it and pass the div's id in parameter.