简体   繁体   中英

How to automatically map a function to a newly added DOM element

I'm trying to automate calling a function (initBox) on all elements with class box on the page in vanilla javascript. I have made a functional solution except that it only applies to elements that are on the page when it is loaded. If I add an element to the DOM using javascript, the function (initBox) is not called on it.

Of course I can call the function (initBox) manually after adding the element, but I would like to automate it.

I'm looking for something similar to what jQuery does for events.

For example:

$('table').on('click', 'td', function (event) {
    doSomething();
});

This event is called even if I add the TD element to the table later via javascript.

Here is my current solution:

 function addBox() { var btn = document.getElementsByTagName('button')[0]; var el = document.createElement('div'); el.classList.add('box'); el.innerText = (document.getElementsByTagName('div').length + 1); btn.before(el); } function initBox(el) { el.innerText += ' Initialized'; } document.querySelectorAll('.box').forEach(initBox);
 .box { display: inline-block; border: 1px solid #1f2227; padding: 20px; } button { padding: 20px; }
 <div class="box">1</div> <div class="box">2</div> <button onclick="addBox()">Add box</button>

The OP's problem can be solved just by the usage of a MutationObserver instance where the OP needs the callback from the list off added nodes just to initialize the very nodes which do match the OP's definition of a box .

 function addBox() { var btn = document.getElementsByTagName('button')[0]; var el = document.createElement('div'); el.classList.add('box'); el.innerText = (document.getElementsByTagName('div').length + 1); btn.before(el); } function initBox(el) { el.innerText += ' Initialized'; } document.querySelectorAll('.box').forEach(initBox); function initializeBoxClassDivOnly(node) { if (node.nodeType === 1 && node.matches('div.box')) { initBox(node); } } function handleNodeInsertion(mutationList/*, observer*/) { for (const mutation of mutationList) { mutation.addedNodes.forEach(initializeBoxClassDivOnly); } }; const observer = new MutationObserver(handleNodeInsertion); observer.observe(document.body, { childList: true, subtree: true });
 .box { display: inline-block; border: 1px solid #1f2227; padding: 20px; } button { padding: 20px; }
 <div class="box">1</div> <div class="box">2</div> <button onclick="addBox()">Add box</button>

Look Into Mutation Observers, they are the new way of observing dom objects, it allows you to run a function when an item is added or removed or modified in a particular DOM element, or if you want you can go old school ( meaning you add event listeners).

Mutation Observers ( Recommended Method ) https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver

Old School Evens https://developer.mozilla.org/en-US/docs/Web/API/MutationEvent

if you want me to write the code, let me know in the comments.

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