简体   繁体   中英

updating a for loop with new dom elements in javascript

I want to add mouse events on to the class .piece even if the divs are created after the DOM is loaded.

Here is my actual loop:

var piece = document.getElementsByClassName('piece');

function theLoop() {
  for(var i=0; i<piece.length; i++) {
    piece[i].addEventListener("mousemove", function(event) {
      //do stuff
    }
  }
}

theLoop();

It works fine, but if I add new divs with the class .piece after the DOM loaded, the loop ignores them.

I add those new divs with .cloneNode() and .appendChild() , like this :

function createPiece(symbol, name) {
  var clone = document.getElementById(symbol).cloneNode(true);
  clone.setAttribute('id',symbol+'-'+name);
  document.getElementById(name).appendChild(clone);
}

createPiece(symbol, name);

All the original cloned divs have the class .piece .

How can I add those new divs to my for loop, and have the mouse event attached to them?

Thanks.

If your loop runs on page load, it's not possible to make it account for elements added to the DOM dynamically afterwards. Usually, event delegation would be a solution, but it's not a good solution for the mousemove event (since it fires so often).

What you could do is create a function that adds the event handler to a passed element. You could then call that function from your current loop, and call it again after adding each new element to the DOM.

Put a mousemove event handler on a common parent of all the pieces and then examine e.target in the event data structure to see which piece the event actually occurred on.

This is called delegated event handling and allows you to install just one event handler on a static parent that will give you events from all children, even children that are dynamically added later.

The only other option is to install an event handler on each specific piece when it's later added to the page. You would need to trigger this from the actual code that adds the element to the page as there is no well-supported, cross-browser way to watch for DOM modifications. If you do it this way, you will need to make your event handling function a named function (rather than the anonymous function you are using now) so that you can use the same function in multiple places.

You don't need the loop for newly created elements. Nor do you need event delegation (though it can be useful) .

Just make the handler a named function, and bind when you clone.

var piece = document.getElementsByClassName('piece');

function pieceHandler(event) {
  //do stuff
}

function theLoop() {
  for(var i=0; i<piece.length; i++) {
    piece[i].addEventListener("mousemove", pieceHandler, false)
  }
}

theLoop();

function createPiece(symbol, name) {
    var clone = document.getElementById(symbol).cloneNode(true);
    clone.addEventListener("mousemove", pieceHandler, false); // assign handler
    clone.setAttribute('id',symbol+'-'+name);
    document.getElementById(name).appendChild(clone);
}

createPiece(symbol, name);

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