多个事件处理程序仅在第一个元素上触发,而不在目标上

时间:2018-08-02 11:27:31

标签: javascript events

因此,我尝试制作一个内容更多/更少的内容切换功能,在我开始添加更多要切换的框之前,它工作得很好。我阅读了使用多个事件处理程序的建议,建议是使用document.getElementsByClassName();。并遍历它们,但是单击第二个按钮时不会显示/隐藏正确的内容,只有第一个。

感谢您的帮助。比较简单的方法是使用jQuery或为按钮分配不同的ID并在每个按钮上调用函数,但是我敢肯定,必须只创建/调用一次事件侦听器,并使它在随后添加的每个元素上起作用。

这是我的代码:

HTML

<div class="card">
  <div class="cardLessContent">
    <h1>Here is a card</h1>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent auctor mi sollicitudin, tristique tortor eget, tempus elit. Vestibulum ante leo, aliquam ac dapibus at, auctor vitae ligula.</p>
  </div>
  <div id="cardMoreContent" class="cardMoreContent">
    <p> Nam finibus nec augue at semper. Quisque sit amet ex eu augue rutrum aliquet. Suspendisse dui enim, gravida quis turpis a, auctor pellentesque velit.</p>
  </div>
  <button id="toggleContent" class="toggleContent toggledOff">More</button>
</div>

<div class="card">
  <div class="cardLessContent">
    <h1>Here is a card</h1>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent auctor mi sollicitudin, tristique tortor eget, tempus elit. Vestibulum ante leo, aliquam ac dapibus at, auctor vitae ligula.</p>
  </div>
  <div id="cardMoreContent" class="cardMoreContent">
    <p> Nam finibus nec augue at semper. Quisque sit amet ex eu augue rutrum aliquet. Suspendisse dui enim, gravida quis turpis a, auctor pellentesque velit.</p>
  </div>
  <button id="toggleContent" class="toggleContent toggledOff">More</button>
</div>

JavaScript

const btnToggleContent = document.getElementsByClassName("toggleContent");
const cardMoreContent = document.getElementById("cardMoreContent");

var toggleContent = function() {
    cardMoreContent.classList.toggle("showing");
    this.classList.toggle("toggledOff");

    if(this.classList.contains("toggledOff")) {
      this.innerHTML = "More";
    }
    else {
      this.innerHTML = "Less";
    }
}

for (var i = 0; i < btnToggleContent.length; i++) {
  btnToggleContent[i].addEventListener("click", toggleContent);
}

JSFiddle:https://jsfiddle.net/jw3qe9xf/6/

3 个答案:

答案 0 :(得分:1)

Id属性在HTML中应该是唯一的,否则它将仅选择该ID的第一个出现。在您的情况下,您始终会切换第一个cardMoreContent

这里是使用event.target

为您提供的简单解决方案

JavaScript

const btnToggleContent = document.getElementsByClassName("toggleContent");
const cardMoreContent = document.getElementById("cardMoreContent");

var toggleContent = function(e) {
    e.target.previousElementSibling.classList.toggle("showing");
    this.classList.toggle("toggledOff");

    if(this.classList.contains("toggledOff")) {
      this.innerHTML = "More";
    }
    else {
      this.innerHTML = "Less";
    }
}

for (var i = 0; i < btnToggleContent.length; i++) {
  btnToggleContent[i].addEventListener("click", toggleContent);
}

JSFiddle:https://jsfiddle.net/c1gdjk25/

答案 1 :(得分:0)

是,仅适用于第一个。这是原因:  您已经多次将'id =“ toggleContent”'相同的id值用于多个元素,这在基本上是错误的。

Id属性必须是唯一的!

使用此答案中的示例: How to get child element by class name?

您将仅需要childNodes并对其进行循环拖曳。

依靠您还可以从子元素中搜索子...

答案 2 :(得分:0)

在删除所有id属性后,将您的javascript代码更改为:

background