简体   繁体   中英

How do I add event listeners to HTML elements if I do not know when they will be created?

I would like to separate my code from my UI in my web page and I would like to know if there is an event I can use that will tell me if an element is created so I can assign an event handler to it at the time it's created.

For example, if I had two elements, and they each have event handlers, how can I tell when those elements have been created and then add them?

What I have so far is to add a listener to the document to a "addElement" event, if one exists. I don't know if one exists. If it does than, check if the element matches any existing id's in a dictionary of functions. So something like this:

Code from separate script file:

<script>
    // event handler for BorderContainer1282
    function doSomething1() {

    }

    // event handler for Button925
    function doSomething2() {

    }

    var clickHandlersDictionary = {};
    clickHandlersDictionary["BorderContainer1282"] = doSomething1;
    clickHandlersDictionary["Button925"] = doSomething2;


    function createComplete() {
        document.addEventListener("added", addElementEventHandlers);
    }

    function addElementEventHandlers(event) {
        var element = event.currentTarget;

        if (clickHandlersDictionary[element.id]!=null) {
            element.addEventListener("click", clickHandlersDictionary[element.id]);
        }
    }
</script>

And the HTML:

<body onReadyState="creationComplete()">
    <div id="BorderContainer1282">
        <input id="Button925" type="button" value="Button">
    </div >
</body>

I think what I might be trying to do is dependency injection but I'm not sure. I may eventually try and support states and that case event listeners would need to be added and also removed when an HTML element is created.

You can use a MutationObserver . MutationObservers allow you to detect changes to DOM and react accordingly.

Take the following for example:

 /***** Setting up some of your code *****/ function doSomething1() { console.log('Do something 1'); } function doSomething2() { console.log('Do something 2'); } var dictionary = { BorderContainer1282: doSomething1, Button925: doSomething2 }; /***** Setting up the observer *****/ // select the target node var target = document.getElementById('target'); // create an observer instance var observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { Object.keys(dictionary).forEach(function(key) { var query = target.querySelector('#' + key); if (query) { query.addEventListener('click', dictionary[key]); } }); }); }); // pass in the target node, as well as the observer options observer.observe(target, { childList: true }); /***** Just adds to the DOM when you click on the button *****/ function addToDom(button) { button.parentNode.removeChild(button); var parentDiv = document.createElement('div'); parentDiv.textContent = 'Parent'; var childDiv1 = document.createElement('div'); childDiv1.textContent = 'BorderContainer1282 (Click Me)'; childDiv1.id = 'BorderContainer1282'; var childDiv2 = document.createElement('div'); childDiv2.textContent = 'Button925 (Click Me)'; childDiv2.id = 'Button925'; parentDiv.appendChild(childDiv1); parentDiv.appendChild(childDiv2); target.appendChild(parentDiv); } 
 <button onclick="addToDom(this)">Add to DOM</button> <div id="target"></div> 

The MutationObserver picks up changes to the target element (which could be any element, including just the body ). In this particular case, it searches the added nodes for any matches to elements in the dictionary. If if finds them, it adds the corresponding function to the click listener.

You need to use event delegation.

If your target div , where you expect new elements to be created, has an id of tgt , you could code an event listener like so:

document.getElementById("tgt").addEventListener("click",function(event){
    alert(event.target.id);
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM