12

I would like add an event such as onclick or mouseover to a dynamically created element (similar to the .live function in jQuery)...how do I do this using pure javascript without a framework such as jQuery?

document.getElementById('create').onclick = function(){
    var newdiv = document.createElement('div');
    newdiv.addClass('new');
    document.body.appendChild(newdiv);
};

document.getElementsByClassName('newdiv').onclick = function(){
    alert('Success');
};
    
    
#create {
     width:150px;
     height:25px;
     margin-bottom:5px;
     background:#ccc;
     border:1px solid #222;   
}

.new {
    width:200px;
    height:100px;
    background:#ffccff;
    border:1px solid #333;   
}
<html>
    <body>
        <div id="create">
            Click to create div
        </div>
    </body>
</html>

I would like to be able to do this from the newly created divs class instead of an id.

Any help would be greatly appreciated

Liam
  • 27,717
  • 28
  • 128
  • 190
Tony
  • 303
  • 3
  • 8

2 Answers2

26

Create one handler on the document object. Check the target element's class and node name (tag). If they match, proceed with whatever needs to be done, otherwise ignore the click.

document.onclick = function(event) {
    var el = event.target;
    if (el.className == "new" && el.nodeName == "DIV") {
        alert("div.new clicked");
    }
};

Here's a fiddle.

Anurag
  • 140,337
  • 36
  • 221
  • 257
  • jQuery's `live` method of even listening works in this fashion, upvote! – Chris Cherry Mar 21 '11 at 00:08
  • Very nice, this is exactly what I'm looking for...not sure why I didn't think of this. Thanks! – Tony Mar 21 '11 at 00:13
  • Note that in this particular case when you work with HTMLAnchorElement (A tag), in order to prevent the default execution (when you click on link) with `return false` you will have to call the `event.preventDefault()` first. – Slavik Meltser May 26 '14 at 11:57
  • Optimization hint: I would suggest to flip these two conditions, just because of short evaluation. Probably second condition will filter out elements more often :) if (el.nodeName == "DIV" && el.className == "magic") { ... } – lukyer Jul 25 '16 at 14:25
  • @lukyer - I would measure this piece of code to see if this is really a bottleneck. Regarding the short-circuiting, are you suggesting there would be fewer `div`elements compared to elements having class `new`? This is purely data-dependent but I would expect to find more divs generally speaking. – Anurag Jul 25 '16 at 20:52
3

@Anurag's answer is correct but not complete and in most cases will result a lot of integration bugs.

Here is the correct version:

document.addEventListener("click", function(event)
{
    // retrieve an event if it was called manually
    event = event || window.event;

    // retrieve the related element
    var el = event.target || event.srcElement;

    // for all A tags do the following
    if (el instanceof HTMLAnchorElement )
    {
        //required to make the "return false" to affect
        event.preventDefault();

        window.location.href = "/click.php?href="+encodeURIComponent(el.href);

        //prevent user's click action
        return false;
    }
}, true);

This is a basic click-trace functionality affects all links on page to trace/record all link clicks.

Community
  • 1
  • 1
Slavik Meltser
  • 9,712
  • 3
  • 47
  • 48
  • 2
    The `return false` here doesn't actually do anything -- that's a jQuery invention that calls event.preventDefault for you. See http://stackoverflow.com/a/1357151/589391. – gsf Jul 28 '14 at 22:01