【问题标题】:How best to sort products on js?如何最好地在 js 上对产品进行排序?
【发布时间】:2019-04-01 09:48:09
【问题描述】:

我有这段代码,但它不能正常工作。

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 应用于类别不匹配的块。最好的方法是什么?

【问题讨论】:

  • 为什么不向所有其他 div 显示:none,除了选中的那个。这里需要搜索什么? (我假设只有 3 个 div)
  • 必须只显示类别属性与所选option的类别属性重合的div,其他全部隐藏

标签: javascript html ecmascript-6


【解决方案1】:

您的代码存在许多问题,并且您的 HTML 无效。

HTML5 中没有定义category 属性。如果要使用自定义属性,则应以data-* 为前缀。对于select 选项,您应该只使用value 属性。

修正后,逻辑只需要:

  1. select 元素中获取所选值(如果它发生变化)。
  2. 循环遍历产品 div 元素,并为每个元素:
    • 如果选择的类别为all,或者与元素的data-category匹配,则将显示样式设置为默认(''
    • 否则将显示样式设置为none

这是一个完整的sn-p:

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>

【讨论】:

    【解决方案2】:

    它工作正常。让我知道这是你的期望

    
    <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>
    

    【讨论】:

      【解决方案3】:

      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>

      【讨论】:

        【解决方案4】:
        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>

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-03-31
          • 1970-01-01
          • 2021-11-02
          • 2010-12-08
          • 1970-01-01
          • 1970-01-01
          • 2013-01-15
          • 1970-01-01
          相关资源
          最近更新 更多