The code that produces the headache for me is rather simple:
$(function(){
$("#test").append('<img onload="alert(\'hi\')" src="Image.jpg"/>');
})
I have the above code in my head and a div with id 'test' in the body. Now my problem is that the page produces two alerts when the image is loaded, but I expected it to produce only one as the 'onload' should be triggered only once- The way it happens when I add the image manually without any javascript..
See the fiddle I made at: /
Any help/explanation is greatly appreciated...
The code that produces the headache for me is rather simple:
$(function(){
$("#test").append('<img onload="alert(\'hi\')" src="Image.jpg"/>');
})
I have the above code in my head and a div with id 'test' in the body. Now my problem is that the page produces two alerts when the image is loaded, but I expected it to produce only one as the 'onload' should be triggered only once- The way it happens when I add the image manually without any javascript..
See the fiddle I made at: http://jsfiddle/9985N/
Any help/explanation is greatly appreciated...
Share Improve this question asked May 30, 2012 at 12:13 ErricErric 8071 gold badge10 silver badges32 bronze badges 5-
Using
.html(...)
method will fix it, but I have no idea why is this happening – Teneff Commented May 30, 2012 at 12:26 -
May be offtopic, but you should never attach
load
on images. – Jashwant Commented May 30, 2012 at 12:53 - 1 @Jashwant: Could you explain why? 'coz I dint see w3c guys mention anything about that at :w3schools./jsref/event_img_onload.asp – Erric Commented May 30, 2012 at 13:15
- First see this w3fools and then jQuery load – Jashwant Commented May 30, 2012 at 13:26
- w3shools may not provide good stuff for learning but its good for element reference,about the caveats mentioned @ jquery api site -seems reasonable but that doesn't mean we should 'never' use it (as I understand it)...The only feature I required here was cross-browser patibility and it seems fine with most modern browsers (for example: I don't want the function to be called if the image is cached..) – Erric Commented May 30, 2012 at 14:36
2 Answers
Reset to default 6UPDATED (Because some people don't believe me, lol)
Because .append
creates the node first and then moves it to its appropriate position. Try appending the element first then adding its attributes as follow:
$(function() {
$("#test").append(
$("<img />").attr({
src: "http://upload.wikimedia/wikipedia/mons/thumb/1/1a/Bachalpseeflowers.jpg/300px-Bachalpseeflowers.jpg",
onload: "alert(\'hi\')"
})
);
});
My answer does not "avoid" the problem, it answers it very directly. If you open the jQuery.js file in unpressed format you can clearly see that .append
creates the node
on the document which is when the onload
event is first called and then shifts
it into position which is when it gets called again. Perhaps shift is the wrong word, forgive me as vocabulary is not my strong suit. However if you follow the code you see its creation and its movement, however the same is not said for using append again to move it, as the node is already created it simply moves from one element to another with no respark of onload. As I said, not sure best terminology, but it's very easy to follow along on the jQuery.js.
Don't believe me? Just tested the following fiddle in MSIE9, FF12, & GoogleChrome20 with 0 problems.
jsFiddle
just FYI, it's not really a horrible practice, but I see people write whole lines of HTML in jQuery all the time and that kind of defeats the purpose. It's a library with many books to read on purpose. Sometimes a plete line of HTML might seem easier, but it may not be faster as it doesn't follow all the great layout work that has been done for you. The idea is to "Write less, do more" and this includes HTML. After all, if you were gonna write the whole line of HTML, why use jQuery at all when you could just PHP it in!? :P Just a thought.
or this:
var img = $('<img src="http://upload.wikimedia/wikipedia/mons/thumb/1/1a/Bachalpseeflowers.jpg/300px-Bachalpseeflowers.jpg"/>').on('load', function(){
$('#test').append(img);
alert('loaded');
});