tags:

views:

101

answers:

3

Consider the javascript / jQuery code:

  jQuery("<input/>").attr("type", "button").attr("value", "Click me")
     .click(function()
     {
        alert("hello");
     })
     .appendTo(".someDiv");

This creates a button, binds an event handler to it and appends it to all elements with class "someDiv".

This works as expected ONLY if there is ONLY ONE element with class "someDiv" in the document. If there are more, the buttons are shown, but the click event is not fired.

I'm aware that I can use the following workaround:

  jQuery(".someDiv").each(function()
  {
     jQuery("<input/>").attr("type", "button").attr("value", "Click me")
        .click(function()
        {
           alert("hello");
        })
        .appendTo(this);
  });

Which works, but is arguably less elegant.

I guess it has something to do with that in the first example there is only one element created and that same element is appended to all "someDiv"s, while in the second example there are actually multiple elements created, but I don't understand why that would mean that the event handler doesn't work in the first example.

A: 

Have you tried something like this:

  jQuery("<input/>").attr("type", "button").attr("value", "Click me")
                                           .appendTo(".someDiv");
     jQuery('.someDiv input[type=button]').click(function()
     {
        alert("hello");
     });
karim79
That's a workable solution as well, but it doesn't explain the "why" of the original problem. :)
Knut Arne Vedaa
@Knut Arne Vedaa - To be honest, I'm not entirely sure why the first one does not work. I can *guess* that it's because the click event handler will not stick because appendTo implicitly creates copies of the element without the attached event handler, when called on a selector that returns multiple elements.
karim79
A: 

That's kind of an odd way to do it. I'd wire it up with live.

$("input[type=button]").click(function() {
  alert("hello");
});

Also not sure what multiple attr calls does for you:

(".someDiv").append("<input type='button' value='Click me' />");
Andy Gaskell
Multiple attr calls helps avoid "this 'kind' of 'apostrophe' usage". It just looks cleaner to me, probably a subjective thing. :)
Knut Arne Vedaa
A: 

I think what you are looking for is clone(true). It will make a copy of the DOM element and its event handlers.

 jQuery("<input/>").attr("type", "button").attr("value", "Click me")
 .click(function()
 {
    alert("hello");
 })
 .clone(true)
 .appendTo(".someDiv");
Jataro
No, that didn't work, unfortunately.
Knut Arne Vedaa
Tested and works with jQuery 1.3.2
Jataro