1

I use addEventListener to add a callback with arguments, but something is wrong

I implement a modal dialog component with overlay: When click on button, the modal will display. When click on overlay, the modal will disappear.

html:

<button class="common-btn">Click me to show a common modal</button>
<div class="modal common">
    <div class="modal-overlay"></div>
    <div class="modal-content">
        <div>This is a common modal</div>
    </div>
</div>

css:

.modal {
  display: none;
  position: fixed;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  z-index: 900;
}

.modal .modal-overlay {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background-color: #fff;
  z-index: 910;
}

.modal .modal-content {
  padding: 20px;
  border: 1px solid #000;
  border-radius: 5px;
  position: absolute;
  top: 50%;
  left: 50%;
  -webkit-transform: translateX(-50%) translateY(-50%);
          transform: translateX(-50%) translateY(-50%);
  z-index: 920;
}

js:

const commonBtn = document.querySelector('.common-btn');
const commonModal = document.querySelector('.modal.common');

function toggleModal(modalEle) {
    console.log('func is called');
    const preModalDisplay = modalEle.style.display;
    if (preModalDisplay === 'block') {
        modalEle.style.display = 'none';
        modalEle
            .querySelector('.modal-overlay')
            .removeEventListener('click', () => {
                toggleModal(modalEle);
            });
    } else {
        modalEle.style.display = 'block';
        modalEle.querySelector('.modal-overlay').addEventListener('click', () => {
            toggleModal(modalEle);
        });
    }
}

commonBtn.addEventListener('click', () => {
    toggleModal(commonModal);
});

The expected results should be:

click on btn: display
click on overlay: disappear
click on btn: display
click on overlay: disappear
click on btn: display
click on overlay: disappear
...

But the actual results is:

click on btn: display
click on overlay: disappear
click on btn: display
click on overlay: still display, and the callback func is called twice

There is something wrong with callback, could anybody tell me what is the problem? Thanks.

Felipe Augusto
  • 7,733
  • 10
  • 39
  • 73
Zhang Kai
  • 21
  • 2
  • You have to remove the exact same reference to the function you add with `addEventListener` in `removeEventListener`. By using two inline arrow functions, you're creating two separate functions. You could try extracting that arrow function to a separate function (outside of `togglemodal`). i'm not posting this as an answer because I believe this is basically this question here: https://stackoverflow.com/questions/10444077/javascript-removeeventlistener-not-working – Khauri Jun 16 '19 at 15:53
  • Possible duplicate of [Javascript removeEventListener not working](https://stackoverflow.com/questions/10444077/javascript-removeeventlistener-not-working) – str Jun 16 '19 at 16:20
  • And i think your `overlay` is going to be displayed only when the modal is open, so No need to keep `adding` and `removing` the event listeners. You can follow the same way as you have followed for `commonBtn`.(add it once) – Panther Jun 16 '19 at 16:33

0 Answers0