通过多个下拉列表过滤对象

filter objects by multiple dropdowns

我有很多按钮,每个按钮有三个 class。第一个 class 可以是 "a1"、"a2" 或 "a3"。第二个 class 可以是 "b1"、"b2" 或 "b3"。第三个 class 与 "c" 相同。例如:

<body>
 <button type="button" class="a1 b3 c3">Button 1</button>
 <button type="button" class="a1 b3 c1">Button 2</button>
 <button type="button" class="a2 b2 c2">Button 3</button>
 <button type="button" class="a3 b1 c3">Button 4</button>
</body>

我想做的是过滤这些按钮,使它们仅在每种 class:

的下拉菜单中选择合适的 classes 时可见
 <select name="a"> 
    <option>all</option> 
    <option>a1</option> 
    <option>a2</option>
    <option>a3</option>
 </select>

 <select name="b"> 
    <option>all</option> 
    <option>b1</option> 
    <option>b2</option>
    <option>b3</option>
 </select>

 <select name="c">
    <option>all</option> 
    <option>c1</option> 
    <option>c2</option>
    <option>c3</option>
 </select>

例如:如果在下拉菜单中选择了 a "a1" 和 b "b3" 以及 c "all",则按钮 1 和按钮 2 应该是可见的。 另一点是,如果在下拉菜单中选择 "a1",则在菜单 b 中应该只有 "all" 和 "b3" 可见。

感谢您的帮助

好的。所以我在每个按钮上添加了一个 group-class 这样就可以更容易地 select 某个特定的组。如果你想离开组classes,你需要另一种算法all过滤器。

但这里有一个可能的解决方案:

// Define default filters
const filters = {
  a: 'all',
  b: 'all',
  c: 'all',
};

function filterButtons() {
  // Hide all buttons for now
  setDisplay( document.querySelectorAll( 'button' ), 'none' );
  
  // Iterate over filters
  Object.keys( filters ).forEach( key => {
    const className = filters[ key ];
    // Determine to show all buttons of a certain group or just a certain class
    let selector = className === 'all' ? key : className;
    setDisplay( document.querySelectorAll( `.${ selector }` ), 'inline' );
  } );
}

// Helper function to set display style on a HTMLCollection
function setDisplay( collection, display ) {
  [ ...collection ].forEach( button => button.style.display = display );
}

// Adding eventListeners so we recognize changes
[ ...document.querySelectorAll( 'select' ) ].forEach( selector => {
  selector.addEventListener( 'change', ( event ) => {
    // Set filters on dropdown change
    filters[ event.target.name ] = event.target.value;
    // Filter buttons on change
    filterButtons();
  } );
} );
<div>
  <select name="a"> 
    <option>all</option> 
    <option>a1</option> 
    <option>a2</option>
    <option>a3</option>
  </select>

  <select name="b"> 
    <option>all</option> 
    <option>b1</option> 
    <option>b2</option>
    <option>b3</option>
  </select>

  <select name="c">
    <option>all</option> 
    <option>c1</option> 
    <option>c2</option>
    <option>c3</option>
  </select>
</div>

<div>
  <!-- I added the base class so it would be easier to select all of a certain group -->
  <button type="button" class="a b c a1 b3 c3">Button 1</button>
  <button type="button" class="a b c a1 b3 c1">Button 2</button>
  <button type="button" class="a b c a2 b2 c2">Button 3</button>
  <button type="button" class="a b c a3 b1 c3">Button 4</button>
</div>