2017-11-13 52 views
10

Zrobiłem prosty menadżer popup, który użył domeny, aby zdecydować, które wyskakujące okienko powinno być na wierzchu, bez żadnej reguły zindeksowania: po kliknięciu wyskakującego okienka, jest to przesunął się na pierwszej pozycji, więc znajduje się na górze drugiego okna podręcznego. Niestety: ten ruch DOM przerywa zdarzenie onclick w moim popup.onclick nie uruchamia się, jeśli element zostanie ponownie wstawiony do DOM w połowie kliknięcia

Zrobiłem prosty przypadek problemu: poniższy kod powinien wyświetlać zdarzenia z trzema kliknięciami: mousedown, mouseup i click, działa w przeglądarce Firefox i myślę, że działał w poprzednich wersjach Chrome, ale robi to już nie.

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

Czy wiesz, w jaki sposób mogę rozwiązać ten problem, i wrócić moje zdarzenie onclick?

Odpowiedz

4

Jeśli ponowne wstawienie elementu do DOM zatrzyma jego wydarzenie click, to inną opcją będzie przeniesienie jego rodzeństwa.

To wydaje się działać (polecam oglądania w trybie pełnego widoku ponieważ wyjście konsola będzie przerwać wydarzenia jeśli pokrywa div właśnie kliknięciu):

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>

+0

Prace nad Chrome, działa na IE11 (której OP nie), i kontynuuje prace nad Firefox. (Te, które mam pod ręką.) Miło! Dziwne i martwiliby mnie pod względem niestabilności. Ale miły! –

+0

Działa doskonale! Dziękuję Ci bardzo. –

+0

Wygląda łatwiej niż dotknięcie zdarzeń, działa naprawdę dobrze. +1 Byłbym ostrożny z zbyt wieloma rodzeństwami/dziećmi - może to zranić wydajność (Nie jest to problemem dla OP, myślę) –

0

To nie jest tak, że wydarzenie przestaje strzelać, po prostu nie klikasz już elementów div z wydarzeniem.

Uważaj na ZIndexing, ponieważ zIndex jest względny do jego kontenera. Nie możesz mieć kontenera z mniejszym indeksem zIndex niż jego rodzicem lub przeniesiesz go za nim. Rozwiązanie „brudne” ma mieć zindex rosną z każdym kliknięciem:

<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>