Как лучше сортировать товары на JS? - PullRequest
1 голос
/ 01 апреля 2019

У меня есть этот код, но он не работает правильно.

let productBox = document.querySelectorAll('.product');
let selectCategory = document.querySelector('#select-category');
let categoryVal = document.querySelectorAll('#select-category option');

selectCategory.addEventListener('change', () => {
    Array.prototype.forEach.call(categoryVal, catItem => {
        Array.prototype.forEach.call(productBox, prodItem => {
            if((catItem.selected) && (prodItem.category === 
            catItem.category)) {
                prodItem.style.display = 'none'
            }
        })
    })
})
.product {
  border: 1px solid;
  padding: 2px;
  margin: .5rem;
}
<select id="select-category">
    <option category="all">All</option>
    <option category="dinner">Dinner</option>
    <option category="first meal">First meal</option>
    <option category="garnish">Garnish</option>
</select>

<div category="dinner" class="product">Dinner</div>
<div category="first meal" class="product">First meal</div>
<div category="garnish" class="product">Garnish</div>

Мне нужно, чтобы при выборе элемента option display none применялся к блокам, категория которых не совпадает.Каков наилучший способ сделать это?

Ответы [ 4 ]

1 голос
/ 01 апреля 2019

В вашем коде есть ряд проблем, и ваш HTML-код недействителен.

В HTML5 не определен атрибут category.Если вы хотите использовать пользовательские атрибуты, они должны иметь префикс data-*.Для параметров select вы должны просто использовать атрибут value.

После исправления этого логика должна быть такой:

  1. Получить выбранное значение из *Элемент 1014 *, если он изменяется.
  2. Зацикливание элементов div продукта и для каждого элемента:
    • , если выбранная категория all или соответствует data-categoryэлемента, установите стиль отображения по умолчанию ('')
    • , в противном случае установите стиль отображения на none.

Вот полныйфрагмент:

const productDivs = document.querySelectorAll('.product');
const categorySelect = document.querySelector('#select-category');

categorySelect.addEventListener('change', (e) => {
  const category = e.target.value;

  [...productDivs].forEach(pd => {
    const display = pd.dataset.category === category || category === 'all';
    pd.style.display = display ? '' : 'none';
  });
});
<select id="select-category">
  <option value="all">All</option>
  <option value="dinner">Dinner</option>
  <option value="first meal">First meal</option>
  <option value="garnish">Garnish</option>
</select>

<div data-category="dinner" class="product">Dinner</div>
<div data-category="first meal" class="product">First meal</div>
<div data-category="garnish" class="product">Garnish</div>
0 голосов
/ 01 апреля 2019
  1. Я переименовал атрибуты category параметров в value
  2. Я обернул весь код {}, чтобы я мог использовать локальные переменные
  3. Я использовал событие input вместо события change
  4. Я прослушиваю всплывающее событие ввода в документе, чтобы проверить наличие события в добавленном позже содержимом
  5. Я использовал CSS-класс hide вместо установки стиля напрямую
  6. Сначала я устанавливаю класс каждого product на hide (не для опции all), затем я сбрасываю этот класс для элемента с соответствующим значением категории.

console.clear();

{
    document.addEventListener('input', (e) => {
    const selectCategory = document.querySelector('#select-category');
    if (e.target === selectCategory) {
      const productBoxes = document.querySelectorAll('.product');
      const categoryVal = document.querySelectorAll('#select-category option');

      if (selectCategory.value == 'all') {
        show(productBoxes)
      } else {
        hide(productBoxes)
      }
      const matches = document.querySelectorAll(`[category*="${selectCategory.value}"]`)
      show(matches)
    }    

  })
  
  
  const hide = (items) => {
    Array.prototype.forEach.call(items, prodItem => {
      prodItem.classList.add('hide')
    })
  }
  const show = (items) => {
    Array.prototype.forEach.call(items, prodItem => {
      prodItem.classList.remove('hide')
    })
  }
  
}
.product {
  border: 1px solid;
  padding: 2px;
  margin: .5rem;
}

.hide {
  display: none;
}
<select id="select-category">
  <option value="all">All</option>
  <option value="dinner">Dinner</option>
  <option value="first meal">First meal</option>
  <option value="garnish">Garnish</option>
</select>

<div category="dinner" class="product">Dinner: One</div>
<div category="first meal" class="product">First meal</div>
<div category="garnish" class="product">Garnish: one</div>
<div category="garnish" class="product">Garnish: two</div>
<div category="dinner" class="product">Dinner: Two</div>

<div category="dinner" class="product">Dinner: three</div>

<br><br><select><option>totally<option>unrelated<option>select</select>
0 голосов
/ 01 апреля 2019

function selectCategory(element) {
  const value = element.value;
  const products = document.getElementsByClassName('product');
  Array.prototype.forEach.call(products, product => {
    const productAttr = product.getAttribute('category');
    if(value === 'All'){
      product.style.display = 'block';
      return;
    }
    productAttr !== value.toLowerCase() ? 
        product.style.display = 'none' :
        product.style.display = 'block';
  })
}
<select id="select-category" onChange="selectCategory(this)">
    <option category="all">All</option>
    <option category="dinner">Dinner</option>
    <option category="first meal">First meal</option>
    <option category="garnish">Garnish</option>
</select>

<div category="dinner" class="product">Dinner</div>
<div category="first meal" class="product">First meal</div>
<div category="garnish" class="product">Garnish</div>
0 голосов
/ 01 апреля 2019

Работает нормально.Дайте мне знать, это вы ожидаете


<script>
let productBox = document.querySelectorAll('.product');
let selectCategory = document.querySelector('#select-category');
let categoryVal = document.querySelectorAll('#select-category option');

selectCategory.addEventListener('change', (evt) => {
    var selectedValue = evt.currentTarget.value.toLowerCase();
    Array.prototype.forEach.call(productBox, prodItem => {
        if(selectedValue !== 'all' && (prodItem.getAttributeNode('category').value !== 
        selectedValue)) {
            prodItem.style.display = 'none'
        } else {
            prodItem.style.display = 'block'
        }           
    });
});
</script>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...