Я пытаюсь создать простой диалог с этими простыми вариантами использования:

  • когда пользователь щелкает черный фон, пользователь должен закрыть диалоговое окно (теперь просто window.alert)
  • когда пользователь нажимает кнопку в белом div, пользователь должен выполнить это действие

Моя проблема: когда пользователь щелкает любую точку в белом div, функция запускается, когда вместо этого я хочу, чтобы все белые div не реагировали на щелчок.

Есть идеи, как это исправить? CSS или JS решения ценят

const parent = document.getElementById('parent')
const child = document.getElementById('child')
const button = document.getElementById('button')

parent.addEventListener('click', () => window.alert('close'))

button.addEventListener('click', (e) => {
e.stopPropagation()
window.alert('do something else')}
)
.parent {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  background-color: gray;
}

.child {
  width: 200px;
  height: 200px;
  background-color: white;

}
<div id="parent" class="parent">
  <div id="child" class="child">
    some content
    <button id="button">do something else</button>
  </div>
</div>
0
Radex 8 Мар 2021 в 15:22

3 ответа

Лучший ответ

Используйте делегирование событий:

document.addEventListener('click', (evt) => {
  const origin = evt.target;
  console.clear();
  // only do something if the origin clicked
  // is #parent or #button
  if (origin.id === "parent") {
    return console.log('close');
  }
  if (origin.id === "button") {
    return console.log("something else");
  }
});
.parent {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  background-color: gray;
}

.child {
  width: 200px;
  height: 200px;
  background-color: white;

}
<div id="parent" class="parent">
  <div id="child" class="child">
    some content
    <button id="button">do something else</button>
  </div>
</div>
1
KooiInc 8 Мар 2021 в 12:30

Просто добавьте этот код

child.addEventListener('click', (e)=> {
  e.stopImmediatePropagation();
});
const parent = document.getElementById('parent')
const child = document.getElementById('child')
const button = document.getElementById('button')

parent.addEventListener('click', () => window.alert('close'))

button.addEventListener('click', (e) => {
e.stopPropagation()
window.alert('do something else')}
)

child.addEventListener('click', (e)=> {
  e.stopImmediatePropagation();

});
.parent {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  background-color: gray;
}

.child {
  width: 200px;
  height: 200px;
  background-color: white;

}
<div id="parent" class="parent">
  <div id="child" class="child">
    some content
    <button id="button">do something else</button>
  </div>
</div>
0
Pradeep Rajvanshi 8 Мар 2021 в 13:01

События «всплывают». Итак, предполагая, что вы хотели сказать

const child = document.getElementById('child')

Вы можете просто отменить пузырение.

child.addEventListener('click', e => e.stopPropagation())
1
C14L 8 Мар 2021 в 12:29