Показать больше / показать меньше Переключить кнопку для нескольких элементов с чистым JavaScript [No jQuery] - PullRequest
0 голосов
/ 26 октября 2018

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

Требования:

  • Изменить текст кнопки: Переключить текст кнопки с Показать больше элементов на Скрыть элементы после нажатия кнопки. (И наоборот)
  • Множественное свертывание: сценарий должен сделать видимыми несколько элементов
  • Приятно иметь: display: none не жестко закодирован в исходный код, но находится в таблице стилей <style>display: none;</style>
  • Нет jQuery или фреймворков - Чистый минимальный легкий JavaScript

База скриптов:

Я использовал этот скрипт Pure Javascript Show / Hide Toggle в качестве основы и изменил его.

Мой модифицированный фрагмент кода:

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 голосов
/ 26 октября 2018

.querySelector() возвращает первый элемент, соответствующий запросу. Вам понадобится .querySelectorAll(), чтобы получить все совпадения, а затем вам придется перебрать все найденные элементы, чтобы определить, должны ли они быть скрыты или нет. Избегайте .getElementsByClassName(), поскольку это возвращает "список активных узлов" , который не подходит для большинства случаев использования и снижает производительность.

Возможно, вам также понадобится другой класс, который просто указывает, является ли элемент скрываемым или нет, чтобы при отображении всех элементов вы знали, какой из них будет скрыт позже.

Кроме того, по возможности избегайте встроенных стилей. Просто установите классы CSS заранее и добавьте или удалите их с помощью element.classList.add() и element.classList.remove().

Наконец, используйте .innerHTML, только когда строка, которую вы получаете / настраиваете, фактически содержит HTML, который необходимо проанализировать, и когда вы полностью контролируете эту строку. При неправильном использовании он тратит ресурсы и может открыть дыры в безопасности вашего кода. Если строка, с которой вы работаете, не содержит 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>
0 голосов
/ 26 октября 2018

Вам нужно 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>
...