You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

作品集黑白图片滤镜切换按钮问题:激活状态与滤镜移除失效

Fixing Your Portfolio Filter Buttons & Image Grayscale Toggle

Hey there! Let's get your portfolio filters working properly—you've got the grayscale setup right, just a few key issues with event handling, selectors, and DOM structure to fix. Here's a breakdown of the problems and the fully corrected code:

Key Issues in Your Original Code

  • Event target mismatch: Your buttons have nested <a> tags, so clicks were targeting the link instead of the button itself, breaking the active state.
  • Incorrect image selector: $('#img') doesn't match any elements in your HTML—you need to target images based on their parent category classes.
  • Unclosed HTML tags: Your category <div> elements weren't closed, causing DOM parsing errors.
  • Missing filter logic: The code didn't actually toggle filters based on the selected category, it just removed filters from all images.

Corrected Full Code

HTML

<section id="portfolio">
  <div class="button-group filters-button-group">
    <button class="button button-effect" data-filter=".A">A</button>
    <button class="button button-effect" data-filter=".B">B</button>
    <button class="button button-effect" data-filter=".C">C</button>
    <button class="button button-selected" data-filter="*">ALL</button>
  </div>
  <div class="portfolio-images">
    <div class="A">
      <img src="http://fakeimg.pl/365x365/ff0000/" width="50%" height="auto">
    </div>
    <div class="B">
      <img src="http://fakeimg.pl/365x365/ff0000/" width="50%" height="auto">
    </div>
    <div class="C">
      <img src="http://fakeimg.pl/365x365/ff0000/" width="50%" height="auto">
    </div>
  </div>
</section>

CSS

button {
  border: 4px solid green;
  border-top: 0;
  border-right: 0;
  font-size: 10px;
  text-decoration: none;
  color: green;
  display: block;
  margin-bottom: 22px;
  background: transparent;
  cursor: pointer;
  padding: 8px 16px;
}

.button-selected {
  background: rgba(8, 140, 126, 0.5);
  border: 4px solid green;
}

#portfolio {
  text-align: center;
  background: transparent;
  position: absolute;
  width: 100%;
}

.portfolio-images {
  margin-top: 20px;
}

#portfolio img {
  filter: grayscale(100%) opacity(30%);
  transition: filter 0.3s ease; /* Smooth transition for filter toggle */
}

#portfolio img.color-active {
  filter: none;
}

JavaScript

const container = document.getElementById('filters-button-group');
const portfolioImages = document.querySelector('.portfolio-images');

container.addEventListener('click', event => {
  // Get the actual button element, even if clicking inside it
  const clickedButton = event.target.closest('button');
  if (!clickedButton) return; // Exit if click wasn't on a button

  // Remove active class from previously selected button
  const activeItem = container.querySelector('.button-selected');
  if (activeItem) {
    activeItem.classList.remove('button-selected');
  }

  // Skip if clicking the already active button (optional)
  if (clickedButton === activeItem) return;

  // Add active class to the clicked button
  clickedButton.classList.add('button-selected');

  // Get the filter value from the button's data attribute
  const filterValue = clickedButton.getAttribute('data-filter');

  // Reset all images to grayscale first
  const allImages = portfolioImages.querySelectorAll('img');
  allImages.forEach(img => img.classList.remove('color-active'));

  // Apply color to matching images
  if (filterValue === '*') {
    // Show all images in color
    allImages.forEach(img => img.classList.add('color-active'));
  } else {
    // Show only the matching category images in color
    const targetImages = portfolioImages.querySelectorAll(`${filterValue} img`);
    targetImages.forEach(img => img.classList.add('color-active'));
  }
});

What Changed & Why?

  1. Fixed HTML structure: Closed all category <div> tags and added a wrapper for images to make selection easier. Removed unnecessary <a> tags inside buttons—buttons are interactive on their own!
  2. Improved event handling: Used event.target.closest('button') to ensure we always get the button element, even if clicking inside it. This fixes the active state issue.
  3. Targeted filter logic: Instead of a generic selector, we use the button's data-filter value to find matching images. We reset all images to grayscale first, then apply color to the selected category (or all for "ALL").
  4. Smooth transitions: Added a CSS transition to the images so the grayscale toggle feels polished instead of abrupt.
  5. Better button styling: Added cursor: pointer and padding to make buttons more user-friendly, and clarified the active state styles.

Test this out, and your buttons should stay active when clicked, and only the selected category images will pop back to color! 🚀

内容的提问来源于stack exchange,提问作者Lou

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:41:08