0

Using the MutationObserver API, I'm trying to attach events to specific elements when they are loaded into the DOM. Code snippet based on the sample on the spec:

var targetNode = document.getElementById("myDiv");

// Callback function to execute when mutations are observed
var callback = function(mutationsList) {
    for(var mutation of mutationsList) {
        mutation.addedNodes.forEach(function(currentValue, currentIndex, listObj) { 
            if (currentValue.querySelectorAll(".questions").length > 0) {
                //we added the questions
                var elements = document.querySelectorAll(".myList, .ofElements");
                //elements is empty here. After the callback fires, 
                //I can query again and find the elements 
                elements.forEach(function() {
                    this.addEventListener("click", function() {alert(this.name + "=" + this.value)});
                });
            }
        });            
    }
};

// Create an observer instance linked to the callback function
var observer = new MutationObserver(callback);

// Start observing the target node for configured mutations
observer.observe(targetNode, { attributes: false, childList: true });

It's matching .questions when it gets added as a child node to the DOM, but at this point it's not able to find the inputs.

Am I misunderstanding how this works? Or is it possible that the code which adds .myList, .ofElements (I cannot modify the source code) is doing something that interferes?

Don Zacharias
  • 1,544
  • 2
  • 14
  • 31
  • Why not just use event delegation? https://stackoverflow.com/questions/203198/event-binding-on-dynamically-created-elements – Barmar May 24 '18 at 21:19
  • Are the inputs inside `.questions`? If this is all being added dynamically, it may add `.questions` first, then add the inputs after that. So your mutation observer is running in between those steps. – Barmar May 24 '18 at 21:24
  • @Barmar when I put a breakpoint inside the block that matches for `.questions`, I can see the inputs I need inside its innerHTML, but yeah that's the problem, they are not part of the DOM yet. I need to watch the subtree I guess? – Don Zacharias May 24 '18 at 21:35
  • Why are you doing it this way instead of just delegating the event? – Barmar May 24 '18 at 21:36
  • You know what that does totally work. $(document).on("click", ".questions input", function() { alert("clicked me!"); }); – Don Zacharias May 24 '18 at 21:45

0 Answers0