显示更多/显示更少使用纯JavaScript的多个元素的切换按钮[没有jQuery]

时间:2018-10-26 15:06:54

标签: javascript toggle hide show show-hide

我正在尝试创建一个小的脚本,该脚本在单击按钮或链接后显示不同的隐藏HTML项目。

要求:

  • 更改按钮文本:单击按钮后,将按钮文本从显示更多项目切换为隐藏项目。 (反之亦然)
  • 多重折叠:脚本必须使多个元素可见
  • 很高兴:display: none未被硬编码为源代码,但位于样式表中<style>display: none;</style>
  • 没有jQuery或框架-纯粹的最小量轻量级JavaScript

脚本库

我以this Pure Javascript Show/Hide Toggle script为基础并对其进行了修改。

我的修改后的代码段:

var button = document.querySelector('.toggle-button');
var menu = document.querySelector('.item');
button.addEventListener('click', function (event) {
  if (menu.style.display == "") {
      menu.style.display = "none";
      button.innerHTML = "Show more items";
  } else {
      menu.style.display = "";
      button.innerHTML = "Hide items";
  }
}
  );
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item hidden-item" style="display: none;">Item 3</div>
<div class="item hidden-item" style="display: none;">Item 4</div>
<div class="item hidden-item" style="display: none;">Item 5</div>
<button class="toggle-button">Show more items</button>

Codepen:

https://codepen.io/anon/pen/ePxeVE

问题:

我的修改未显示隐藏的项目。我已经在这个问题上花费了几个小时,但是我没有使脚本正常工作。 JavaScript专业人员有什么想法,当单击切换按钮时如何显示和隐藏多个元素?

2 个答案:

答案 0 :(得分:1)

您需要querySelectorAll而不是querySelector来检索和遍历多个元素。我建议改用.hidden类,然后可以遍历.hidden-item s并在每个类上切换类:

const button = document.querySelector('.toggle-button');
const hiddenItems = document.querySelectorAll('.hidden-item');
let isHidden = true;
button.addEventListener('click', () => {
  button.textContent = isHidden
  ? 'Hide items'
  : 'Show more items';
  
  isHidden = !isHidden;
  hiddenItems.forEach(item => item.classList.toggle('hidden'));
});
.hidden {
  display: none;
}
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item hidden-item hidden">Item 3</div>
<div class="item hidden-item hidden">Item 4</div>
<div class="item hidden-item hidden">Item 5</div>
<button class="toggle-button">Show more items</button>

答案 1 :(得分:1)

.querySelector()返回与查询匹配的第一个元素。您需要.querySelectorAll()才能获得所有匹配项,然后必须遍历所有找到的元素以确定是否应该隐藏它们。避免使用.getElementsByClassName(),因为这会返回一个"live node list",不适用于大多数用例并影响性能。

您可能还需要另一个类,该类仅指示一个项目是否可隐藏,以便在显示所有项目时,您将知道稍后再隐藏其中的一个。

此外,请尽可能避免使用内联样式。只需提前设置CSS类,然后使用element.classList.add()element.classList.remove()添加或删除它们即可。

最后,仅当要获取/设置的字符串实际上包含需要解析的HTML并且完全控制该字符串时,才使用.innerHTML。如果使用不当,则会浪费资源,并可能在代码中造成安全漏洞。当您使用的字符串不包含任何HTML或不需要由HTML解析器解析时,请使用.textContent

评论如下:

var button = document.querySelector('.toggle-button');

button.addEventListener('click', function (event) {
  // Get all the hideable items into an Array so that .forEach() can be safely used to loop over them
  let hiddenItems = Array.prototype.slice.call(document.querySelectorAll('.hideable'));
  
  // Are we hiding or showing?
  let showing = button.textContent === "Show more items";
  
  // Loop over the items
  hiddenItems.forEach(function(item){
    if(!showing){
      // If we are hiding, then add the .hidden-item class
      item.classList.add("hidden-item");
    } else {
      // Otherwise remove the .hidden-item class
      item.classList.remove("hidden-item");
    }
    
    // Update the button text:
    button.textContent = button.textContent === "Show more items" ? "Hide items" : "Show more items";
  });
});
/* This could be placed in an external .css file */
.hidden-item { display:none; }
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item hidden-item hideable">Item 3</div>
<div class="item hidden-item hideable">Item 4</div>
<div class="item hidden-item hideable">Item 5</div>
<button class="toggle-button">Show more items</button>