Закрыть всплывающее окно при нажатии на другое всплывающее окно eventListener - PullRequest
1 голос
/ 10 июля 2020

Я использовал eventListener, чтобы закрывать всплывающие окна, когда я нажимаю на них, но всплывающее окно все еще отображается, когда я нажимаю на другое всплывающее окно. Есть ли способ исправить это, не меняя слишком много кода?

Я новичок в JS, поэтому стараюсь делать все как можно проще. В идеале я хочу сохранить функцию eventListener, потому что она очень хорошо работает, чтобы закрывать всплывающие окна без необходимости вручную закрывать каждое из них, кроме этого.

var popup = document.getElementById("myPopup");
  
function myFunction() {
  popup.classList.toggle("show");
}

window.addEventListener('click', ({ target }) => {
  if (!target.closest('.popup') && popup.classList.contains('show')) myFunction();
});

var popup2 = document.getElementById("myPopup2");
  
function myFunction2() {
  popup2.classList.toggle("show");
}

window.addEventListener('click', ({ target }) => {
  if (!target.closest('.popup') && popup2.classList.contains('show')) myFunction2();
});
/* Popup container - can be anything you want */
.popup {
  position: relative;
  display: inline-block;
  cursor: pointer;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

/* The actual popup */
.popup .popuptext {
  visibility: hidden;
  width: 160px;
  background-color: #555;
  color: #fff;
  text-align: center;
  border-radius: 6px;
  padding: 8px 0;
  position: absolute;
  z-index: 1;
  bottom: 125%;
  left: 50%;
  margin-left: -80px;
}

/* Popup arrow */
.popup .popuptext::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  margin-left: -5px;
  border-width: 5px;
  border-style: solid;
  border-color: #555 transparent transparent transparent;
}

/* Toggle this class - hide and show the popup */
.popup .show {
  visibility: visible;
  -webkit-animation: fadeIn 1s;
  animation: fadeIn 1s;
}
<body style="text-align:center">
<h2>Popup</h2>

<div class="popup" onclick="myFunction()">Click me to toggle the popup!
  <span class="popuptext" id="myPopup">A Simple Popup!</span>
</div>

<h2>Popup2</h2>

<div class="popup" onclick="myFunction2()">Click me to toggle the popup!
  <span class="popuptext" id="myPopup2">A Simple Popup again!</span>
</div>


</body>

Ответы [ 3 ]

1 голос
/ 10 июля 2020

Вы очень близки, но то, как вы это написали, усложняет задачу. Мы можем лучше решить эту проблему, используя функцию forEach l oop и generi c:

JSFiddle: https://jsfiddle.net/vpr4Lh62/

// constants
const SHOW_CLASS = 'show'

// clears any active popups by removing the show class from all popup texts
// note: could be further optimized by storing the "active" popup in a variable whenver it's clicked, and only unsetting that one in this function
const clearPopups = () => {
  document.querySelectorAll('.popuptext').forEach(text => text.classList.remove(SHOW_CLASS))
}

// keep behavior to clear popups when clicking outside of popup
window.addEventListener('click', ({ target }) => {
    if(!target.classList.contains('popup')) {
    clearPopups()
  }
})

// instead of creating click handlers for each popup, we can create them all at once using a forEach loop

// first grab all the popups on the page
const popups = document.querySelectorAll('.popup')

// set a click handler on each popup
popups.forEach(popup => {
  // we can also set the event listener on the popup, instead on the entire window
  popup.addEventListener('click', ({ target }) => {
    // grab the first child, which will be the span
    const span = popup.children[0]
    // clear all the popups first
    clearPopups()
    // then set this one to be shown
    span.classList.add(SHOW_CLASS)
  })
})

Это также означает мы можем упростить наш HTML:

<body style="text-align:center">
<h2>Popup</h2>

<!-- You should never use onclick, this is old. Click handlers should be set using javascript -->
<div class="popup">Click me to toggle the popup!
  <!-- We also don't need the ID here anymore -->
  <span class="popuptext">A Simple Popup!</span>
</div>

<h2>Popup2</h2>

<div class="popup">Click me to toggle the popup!
  <span class="popuptext">A Simple Popup again!</span>
</div>


</body>
0 голосов
/ 10 июля 2020

Это решение вашей проблемы.

Mohd Belal Toggle popus JsFiddle

Точки, указанные в этом jsfiddle

1. 2 Popus have been taken for now
2. Popus will toggle other popup opened
3. Clicking on area other than popup will close the popup

Надеюсь на вас получил свое решение @ Joe

0 голосов
/ 10 июля 2020

Чтобы сохранить простоту и минимальное количество изменений (но далеко не идеальное решение), это:

Для обработчиков щелчков окна вам нужно иметь возможность различать два всплывающих окна, в настоящее время вы используют класс .popup в качестве проверки, не является ли он ближайшим в обоих случаях, поэтому, когда вы нажимаете на второе всплывающее окно, myFunction() не выполняется.

Я добавил сюда новый класс имена всплывающих окон, 'one' и 'two' соответственно.

<body style="text-align:center">
<h2>Popup</h2>

<div class="popup one" onclick="myFunction()">Click me to toggle the popup!
  <span class="popuptext" id="myPopup">A Simple Popup!</span>
</div>

<h2>Popup2</h2>

<div class="popup two" onclick="myFunction2()">Click me to toggle the popup!
  <span class="popuptext" id="myPopup2">A Simple Popup again!</span>
</div>


</body>

Затем в коде javascript вы можете настроить их таргетинг, слегка изменив селекторы:

var popup = document.getElementById("myPopup");
  
function myFunction() {
  popup.classList.toggle("show");
}

window.addEventListener('click', ({ target }) => {
  if (!target.closest('.popup.one') && popup.classList.contains('show')) myFunction();
});

var popup2 = document.getElementById("myPopup2");
  
function myFunction2() {
  popup2.classList.toggle("show");
}

window.addEventListener('click', ({ target }) => {
  if (!target.closest('.popup.two') && popup2.classList.contains('show')) myFunction2();
});

Опять же, это ни в коем случае не хороший стандарт кодирования и не лучшее решение, а, по сути, простейший с наименьшими изменениями в коде. Я надеюсь, что это поможет понять причину возникновения проблемы.

...