1

I am populating a table with an XML file, I have a column that links to more details. Because of the way I'm running the web page (Chrome extension) I need to dynamically add an event handler when the table is populated.

I have this working...

document.addEventListener('DOMContentLoaded', function () {
document.getElementById("detailLink").addEventListener('click',
    clickHandlerDetailLink); });

function clickHandlerDetailLink(e) {   detailLinkPress('SHOW'); }

function detailLinkPress(str) {
alert("Message that will show more detail");
}

But how do I go about adding the event handler dynamically? I have assigned all the fields in that column the id of detailLink.

2 Answers 2

3

You probably need to listen for a mutation event for the table, and then check each time the target element which has fired the event. Previously it used to be these events "DOMNodeInserted", or "DOMSubtreeModified", but they were very slow so according to new specifications the listener is called MutationObserver (which is much faster than the previous ones). This is an example from some Mozilla webpage edited for my testing :

var observer = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
    alert(mutation.target.id + ", " + mutation.type + 
    (mutation.addedNodes ? ", added nodes(" + mutation.addedNodes.length + "): " + printNodeList(mutation.addedNodes) : "") + 
    (mutation.removedNodes ? ", removed nodes(" + mutation.removedNodes.length + "): " + printNodeList(mutation.removedNodes) : ""));
  });   
});

// configuration of the observer:
var config = { attributes: false, childList: true, characterData: false };

var element = document.getElementById('TestID');

// pass in the target node, as well as the observer options
observer.observe(element, config); 

function printNodeList(nodelist)
{
    if(!nodelist)
        return "";
    var i = 0;
    var str = "";
    for(; i < nodelist.length; ++i)
        str += nodelist[i].textContent + ",";

    return str;
}
Sign up to request clarification or add additional context in comments.

Comments

2

If you want to assign an event to an element that doesn't yet exist, or to a series of elements (without creating one for each element), you need a delegate. A delegate is simply a parent element that will listen for the event instead of all the children. When it handles the event, you check to see if the element that threw the event is the one you're looking for.

If the parent <table> always exits, that would be a good place to add the listener. You can also add it to body. Also, you shouldn't be using detailLink as an id for more than one element. Use class instead.

Demo: jsFiddle

Script:

document.body.addEventListener( 'click', function ( event ) {
    if( event.srcElement.className == 'detailLink' ) {
        detailLinkPress( 'SHOW' );
    };
} );

function detailLinkPress( str ) {
    alert("Message that will show more detail");
};

HTML:

<div class="detailLink">click me</div>

1 Comment

If my event is focus, it seem don't work. How should I do?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.