带有img的div单击事件,单击img时文本不触发

时间:2018-11-19 20:10:43

标签: javascript html ecmascript-6 toggle

我在ES6 / vanilla JS中编写了切换脚本。预期的功能非常简单,只需单击切换div,它将active类添加到与切换div的data-toggle属性匹配的另一个div中。在我的切换div中,我需要同时包含文本和图像。当您单击div中的文本时,它的效果很好,但是,当您单击div中的图像时,则不会触发切换。我需要做些具体的事情来将div中的所有孩子包括在内吗?

由于某种原因,我什至无法通过此代码段编辑器来使它工作,但它在我的项目中正在工作。

const setActive = (toggles, panels, id) => {
  let activePanel = panels.filter(panel => panel.getAttribute('data-toggle') == id)
  let activeToggle = toggles.filter(toggle => toggle.getAttribute('data-toggle') == id)
  activePanel.forEach(panel => panel.classList.add('active'))
  activeToggle.forEach(toggle => toggle.classList.add('active'))
}

const removeActive = (nodes) => {
  nodes.forEach(node => node.classList.remove('active'))
}

const handler = (event) => {
  event.preventDefault()
  let id = event.target.getAttribute('data-toggle')
  let panels = Array(...document.querySelectorAll('.js-toggle-panel'))
  let toggles = Array(...document.querySelectorAll('.js-toggle'))
  removeActive(panels)
  removeActive(toggles)
  setActive(toggles, panels, id)
}

let toggles = Array(...document.querySelectorAll('.js-toggle'))
toggles.forEach(toggle => toggle.addEventListener('click', handler))
.toggle-panel {
  display: none;
}

.toggle-panel .active {
  display: block;
}
<div class="js-toggle toggle" data-toggle="toggle-1">
  <img src="https://via.placeholder.com/50"> First toggle
</div>

<div class="js-toggle toggle" data-toggle="toggle-2">
  Second toggle
</div>

<div class="js-toggle-panel toggle-panel" data-toggle="toggle-1">
  <h1>Toggle 1</h1>
</div>

<div class="js-toggle-panel toggle-panel" data-toggle="toggle-2">
  <h1>Second toggle!</h1>
</div>

2 个答案:

答案 0 :(得分:2)

您应该在event.target函数中使用event.currentTarget代替handler来返回附加了事件侦听器的节​​点。 event.target返回<img>节点,而不是<div>,返回data-toggle

答案 1 :(得分:2)

我更改了两项我认为可以解决您问题的方法:

  1. 我将选择器.toggle-panel .active更改为.toggle-panel.active -即使这样,即使在JS按照您的意图工作时,实际上也看不到任何内容。
  2. 我将您的代码从使用event.target移到了event.currentTarget -前者始终指向clicked元素,而后者则指向放置侦听器的元素。

请参见下面的代码段。

const setActive = (toggles, panels, id) => {
  let activePanel = panels.filter(panel => panel.getAttribute('data-toggle') == id)
  let activeToggle = toggles.filter(toggle => toggle.getAttribute('data-toggle') == id)
  activePanel.forEach(panel => panel.classList.add('active'))
  activeToggle.forEach(toggle => toggle.classList.add('active'))
}

const removeActive = (nodes) => {
  nodes.forEach(node => node.classList.remove('active'))
}

const handler = (event) => {
  event.preventDefault()
  let id = event.currentTarget.getAttribute('data-toggle')
  let panels = Array(...document.querySelectorAll('.js-toggle-panel'))
  let toggles = Array(...document.querySelectorAll('.js-toggle'))
  removeActive(panels)
  removeActive(toggles)
  setActive(toggles, panels, id)
}

let toggles = Array(...document.querySelectorAll('.js-toggle'))
toggles.forEach(toggle => toggle.addEventListener('click', handler))
.toggle-panel {
  display: none;
}

.toggle-panel.active {
  display: block;
}
<div class="js-toggle toggle" data-toggle="toggle-1">
  <img src="https://via.placeholder.com/50"> First toggle
</div>

<div class="js-toggle toggle" data-toggle="toggle-2">
  Second toggle
</div>

<div class="js-toggle-panel toggle-panel" data-toggle="toggle-1">
  <h1>Toggle 1</h1>
</div>

<div class="js-toggle-panel toggle-panel" data-toggle="toggle-2">
  <h1>Second toggle!</h1>
</div>