最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to add event handler with Prototype new Element() constructor? - Stack Overflow

programmeradmin3浏览0评论

I'm inserting an img tag into my document with the new Element constructor like this (this works just fine):

$('placeholder').insert(new Element("img", {id:'something', src:myImage}))

I would like to trigger a function when this image loads, but I can't figure out the correct syntax. I'm guess it's something like this (which doesn't work).

$('placeholder').insert(new Element("img", 
    {id:'something', src:myImage, onload:function(){alert("MOO")}}))

I'm hoping to do this in the same line of code and not to have to attach an event observer separately.

EDIT: The event needs to be registered when the element is created, not after. If the image loads before the event is attached, the event will never fire.

I'm inserting an img tag into my document with the new Element constructor like this (this works just fine):

$('placeholder').insert(new Element("img", {id:'something', src:myImage}))

I would like to trigger a function when this image loads, but I can't figure out the correct syntax. I'm guess it's something like this (which doesn't work).

$('placeholder').insert(new Element("img", 
    {id:'something', src:myImage, onload:function(){alert("MOO")}}))

I'm hoping to do this in the same line of code and not to have to attach an event observer separately.

EDIT: The event needs to be registered when the element is created, not after. If the image loads before the event is attached, the event will never fire.

Share Improve this question edited Dec 28, 2011 at 11:46 Rob W 349k87 gold badges807 silver badges682 bronze badges asked Nov 10, 2008 at 19:43 Diodeus - James MacFarlaneDiodeus - James MacFarlane 114k33 gold badges163 silver badges180 bronze badges 2
  • Why don't you want two lines of code? Surely that would make things more clear/readable? – mercutio Commented Nov 10, 2008 at 20:20
  • Because if you insert the image in the first line, by the time you get to the second one it is too late to attach the event because the image has already loaded. The event needs to be attached when the element is created, not after. – Diodeus - James MacFarlane Commented Nov 10, 2008 at 21:35
Add a ment  | 

5 Answers 5

Reset to default 4

In this case, the best solution is to not use Prototype or at least not exclusively. This works:

var img = new Element('img',{id:'logo',alt:'Hooray!'});
img.onload = function(){ alert(this.alt); };
img.src = 'logo.jpg';

The key is setting the onload directly instead of letting Prototype's wrapper do it for you, and set the src last (actually not sure about that, but I do it last to be safe).

One-liners are overrated. With proper use of local variables the above is just as good. If you must have a one-liner, create a wrapper function or hack the Prototype core to ensure proper assignment (submit a patch!).

Try

$('placeholder').insert(new Element("img", {
    id: 'something', 
    src:myImage
}).observe('load', function() {
    // onload code here
}));

You might have to move the function elsewhere and call it by name

$('placeholder').insert(new Element("img", 
    {id:'something', src:myImage, onload:"javascript:moo()"}))

function moo() {
    alert("MOO");
}

Of course, because insert returns the element, you could inline Element.observe

$('placeholder').insert(new Element("img", 
    {id:'something', src:myImage})).observe('load', function(){alert("MOO")});

The "onload" code shouldn't need to be wrapped up into an event handler. You are essentially loading the element right there, just put the code after the insert.

var img = new Element('img', {id: 'something', src:'myImage.jpg'});
$('placeholder').insert(img);
// Element has loaded! It can now be mucked around with.
// The onload code goes here...

It kind of sucks, but this is what you need to do:

$('placeholder').insert(new Element("img", {
    id:'something', src:myImage, onload:'alert("MOO")'
}));

The values in the attributes object just get inserted as strings, so when you do "onload: function() {...}" it turns into:

<img onload="function() {...}" />

Which doesn't actually execute the code inside the function, it just defines a new anonymous function that won't execute unless you tell it to.


If you wanted to be a ninja about it, you could do something like this:

var moo = function() { alert("MOO"); };
$('placeholder').insert(new Element("img", {
    id:'something', src:myImage, onload:'(' + moo + ')()'
}));

Or even:

$('placeholder').insert(new Element("img", {
    id:'something', src:myImage, onload:'(' + function() { alert("MOO"); } + ')()'
}));

While kind of crazy, those options give you the actual function object to work with in case you need it.

发布评论

评论列表(0)

  1. 暂无评论