Reputation: 103
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 ?
Upvotes: 10
Views: 1064
Reputation: 101730
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>
Upvotes: 4
Reputation: 415
It's not that event stops firing, it's just that you are not clicking the divs with the event anymore.
Be careful on zIndexing since zIndex is relative to it's container. You cannot have a container with less zIndex than it's parent or you will move it behind it. The "dirty" solution is to have zIndex grow with every click:
<style type="text/css">
html, body{
width: 100%;
height: 100%;
}
.Movable{
height: 100px;
position: absolute;
width: 100px;
}
.black{
background-color: black;
}
.gray{
background-color: gray;
}
.wheat{
background-color: lightgray;
}
<div style="position: relative; z-index: 20;">
<p id="log" style="height: 1em; overflow-y: scroll;"></p>
<div onclick="log( 'clicked', this )" onmousedown="log( 'mousedown', this )" onmouseup="log( 'mouseup', this )" class="Movable black"></div>
<div onclick="log( 'clicked', this )" onmousedown="log( 'mousedown', this )" onmouseup="log( 'mouseup', this )" style="left: 25px; top: 55px;" class="Movable gray"></div>
<div onclick="log( 'clicked', this )" onmousedown="log( 'mousedown', this )" onmouseup="log( 'mouseup', this )" style="left: 55px; top: 75px;" class="Movable wheat"></div>
</div>
<script type="text/javascript">
var index = 1;
function log( msg, element )
{
element.style.zIndex = index++;
document.getElementById( 'log' ).innerHTML += "Log: " + msg + " -> " + element.className + "</br>";
}
</script>
Upvotes: 0