Проверить массив на наличие хотя бы одного условия и не перезаписывать его при последующих проверках - PullRequest
1 голос
/ 19 апреля 2020

Проблема

A для l oop проверяет массив, чтобы убедиться, что он соответствует хотя бы одному условию. Более поздние итерации для l oop, по-видимому, переопределяют исходные совпадения.

Вопрос

Как проверить массив, чтобы увидеть, соответствует ли он хотя бы одному условию, и не иметь более поздних итераций этой проверки переопределяет (и, таким образом, возвращает ложь) результаты?

Цель

Прикрепленный фрагмент кода должен отображать элементы <article>, которые имеют любые совпадения в соответствующих Массив currentItemTags с массивом showOnlyItemsWithTheseTags. Поскольку showOnlyItemsWithTheseTags содержит ["digital", "2016"], это будет означать, что элементы Австралии и Мексики должны отображаться, поскольку оба их currentItemTags содержат совпадение с чем-то в showOnlyItemsWithTheseTags

подход

приведенный ниже код предназначен для выполнения следующих действий:

  1. Перебирает каждый pageItem (три элемента <article>)
  2. Подготавливает массив currentItemTags для pageItem
  3. Зацикливается на массив showOnlyItemsWithTheseTags
  4. Проверяет currentItemTags на совпадения с showOnlyItemsWithTheseTags
  5. Применяет класс Hide / Show CSS в зависимости от того, есть совпадение или нет, соответственно

Я подозреваю, что на шаге 5 все go неправильно. Я попытался применить методы .some () и .filter () безуспешно - не удалось заставить их работать в этом контексте.

// Set up
const pageItems = document.querySelectorAll("main article");

// Changing items in this array should show or hide page items
const showOnlyItemsWithTheseTags = [
  "digital",
  "2016"
];

for (let i = 0; i < pageItems.length; i++) {
  // Access each item
  const currentItem = pageItems[i];

  // Manually deconstruct this item's dataset into one array
  const currentItemTags = [];
  currentItemTags.push(
    currentItem.getAttribute("data-type"),
    currentItem.getAttribute("data-year"),
    currentItem.getAttribute("data-topic"),
    currentItem.getAttribute("data-country")
  );


  // Where I think the problem is:

  // Check this item's dataset array if it contains a matche with showOnlyItemsWithTheseTags
  for (let j = 0; j < showOnlyItemsWithTheseTags.length; j++) {
    
    if (currentItemTags.includes(showOnlyItemsWithTheseTags[j])) {
      // currentItemTags array contains a match with showOnlyItemsWithTheseTags
      // Show this item
      currentItem.classList.remove("hideItem");
      currentItem.classList.add("showItem");
    } else {
      // currentItemTags does not contain ANY match with showOnlyItemsWithTheseTags
      // Hide this item
      currentItem.classList.remove("showItem");
      currentItem.classList.add("hideItem");
    }
  }
}
/* Set up */
body {
  margin: 1rem;
  font-family: sans-serif;
}

article {
  background-color: tomato;
  padding: 1rem;
  margin-bottom: 1rem;
  font-weight: 700;
  font-size: 1.5rem;
}

/* Classes references in JS */
.showItem {
  display: auto;
  /* back to default */
}

.hideItem {
  display: none;
}
<main>
  <article data-type="analog" data-year="2016" data-topic="food" data-country="australia">Analog, 2016, Food, Australia</article>
  <article data-type="digital" data-year="2017" data-topic="art" data-country="mexico">Digital, 2017, Art, Mexico</article>
  <article data-type="analog" data-year="2020" data-topic="music" data-country="poland">Analog, 2020, Music, Poland</article>
</main>

Текущий результат

Отображается только элемент Australia <article>. Мексика тоже должна показать.

1 Ответ

1 голос
/ 19 апреля 2020

Самый простой способ получить все атрибуты данных в JS - это Object.values(element.dataset)

, но если у вас есть другие не имеющие отношения атрибуты данных, выполните
listArray = [element.dataset.type, element.dataset.year, element.dataset.topic, element.dataset.country ]

способ проверки если массив 2 имеет несколько общих элементов:
if (arr1.some(key=>arr2.includes(key)))

полный код:

const pageItems = [...document.querySelectorAll('main article')]
                    .map(el=>({el:el, keys:Object.values(el.dataset)}) );

function articleFiltering( showOnly )
  {
  pageItems.forEach(item=>
    {
    if (showOnly.some(key=>item.keys.includes(key))) 
      { item.el.classList.remove('hideItem') }
    else
      { item.el.classList.add('hideItem')    }
    }) 
  }

const showOnlyItemsWithTheseTags = [ 'digital', '2016' ]; 

articleFiltering( showOnlyItemsWithTheseTags )
body {
  margin: 1rem;
  font-family: sans-serif;
  }
article {
  background-color: tomato;
  padding: 1rem;
  margin-bottom: 1rem;
  font-weight: 700;
  font-size: 1.5rem;
  }
.hideItem {
  display: none;
  }
<main>
  <article data-type="analog"  data-year="2016" data-topic="food"  data-country="australia" > Analog, 2016, Food, Australia </article>
  <article data-type="digital" data-year="2017" data-topic="art"   data-country="mexico"    > Digital, 2017, Art, Mexico    </article>
  <article data-type="analog"  data-year="2020" data-topic="music" data-country="poland"    > Analog, 2020, Music, Poland   </article>
</main>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...