Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

onclick not firing if element is reinserted into DOM mid-click

I made a simple popup manager, which used the dom to decide which popup should be in front, without any z-index rule : when I click on a popup, it's moved in first position, so it is on top of the other popup. Unfortunately : this dom movement breaks the onclick event in my popup.

I made a simple case of the issue : the following code should output the three click events : mousedown, mouseup and click, it works on Firefox, and I think it used to work in previous versions of Chrome, but it doesn't anymore.

<div>
  <div onmousedown="console.log('mousedown');this.parentElement.appendChild(this);" onmouseup="console.log('mouseup');" onclick="console.log('click');">Click</div>
</div>

Do you know how can I fix this issue, and get back my onclick event ?

like image 840
Laurent POSTIC Avatar asked Nov 13 '17 16:11

Laurent POSTIC


1 Answers

If reinserting an element into the DOM stops its click event from firing, then the other option would be to move its siblings.

This seems to work (I recommend viewing in full page mode because the console output will interrupt the events if it covers up a div you've just clicked):

function moveToFront(el) {
  var parent = el.parentElement;

  while (el.nextSibling) { 
    parent.insertBefore(el.nextSibling, el); 
  }
}

[].slice.call(document.getElementsByClassName('moveable')).forEach(function(el) {
  el.addEventListener('mousedown', function() {
    console.log('mousedown', this.id);
    moveToFront(this);
  });
  el.addEventListener('mouseup', function() {
    console.log('mouseup', this.id);
  });
  el.addEventListener('click', function() {
    console.log('click', this.id);
  });
});
.moveable {
  width: 100px;
  height: 100px;
  position: absolute;
}

#div1 {
  background-color: green;
  top: 10px;
  left: 10px;
}

#div2 {
  background-color: red;
  top: 40px;
  left: 40px;
}

#div3 {
  background-color: yellow;
  top: 20px;
  left: 70px;
}
<div>
  <div id="div1" class="moveable">Click</div>
  <div id="div2" class="moveable">Click</div>
  <div id="div3" class="moveable">Click</div>
</div>
like image 77
JLRishe Avatar answered Oct 18 '22 11:10

JLRishe