Search code examples
javascripthtmlmodal-dialogcss-position

Dealing with click event handler on inner div and outer div


I've got modal window: parent div (wrapper with dark transparent background) and child div (with buttons, inputs and text). Both of them are fixed positioning.
In JavaScript I do simple code: If I click on parent fixed div (.modal-wrapper) - it must close (remove) whole modal window. And same result if I click on close button ('X' button in the corner of modal window).

Here is my simple JS code:

function doModalClose() {
   modalWrapper.remove();
}

closeBtn.addEventListener('click', doModalClose);
modalWrapper.addEventListener('click', doModalClose);

And html markup:

<div class="modal-wrapper">
    <div class="modal-window">
        <div class="btn-wrapper"><span class="close-btn"></span></div>
        other modal elements...
    </div>
</div>

The main question is that when I click on parent div it works correctly, and as when I click on .close-btn. But if I clicked on child div (.modal-window) it closes whole modal too, which incorrect!

I make a simple alert(); check: when I click on parent one it should say Modal Wrapper and when I click on child one it should say Modal Window.
And when I click on child window it calls two alert(); functions: first is child's Modal Window and after that parent's Modal Wrapper.
So that's the reason of my issue, but I don't understand the reason of that kind of behavior. I use on child div z-index: 2; and z-index: 1; on parent div, but it still doesn't help.

Thank you for your attention!


Solution

  • This happens because one div is inside another div, which means that if you click the inner div you also click the outer one because the inner is inside the outer one. To solve this issue, you need an extra handler just for the outer div and to use therein event.stopPropagation().

    Run this code snippet and see by yourself.

    function doModalClose() {
       modalWrapper.remove();
    }
    
    var closeBtn = document.getElementsByClassName('close-btn')[0]
    var modalWrapper = document.getElementsByClassName('modal-wrapper')[0]
    var modalWindow = document.getElementsByClassName('modal-window')[0]
    var button1 = document.getElementsByClassName('button1')[0]
    var button2 = document.getElementsByClassName('button2')[0]
    
    closeBtn.addEventListener('click', doModalClose);
    modalWrapper.addEventListener('click', doModalClose);
    
    modalWindow.addEventListener('click', function (event) {
      event.stopPropagation()
    })
    
    button1.addEventListener('click', function (event) {
      alert('button1')
    })
    button2.addEventListener('click', function (event) {
      alert('button2')
    })
    div {margin: 5px; padding: 5px}
    .modal-wrapper {border: 2px solid red}
    .modal-window {border: 2px solid blue}
    .btn-wrapper, .btn {border: 2px solid green}
    <div class="modal-wrapper">modal-wrapper
        <div class="modal-window">modal-window
            <div class="btn-wrapper"><span class="close-btn">button</span></div>
            <a class="btn button1">Button1</a>
            <a class="btn button2">Button2</a>
        </div>
    </div>