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

如何用JavaScript实现点击盒子后模糊其余背景及未点击元素

实现点击Box后模糊其他背景元素的解决方案

要实现点击某个Box后,模糊蓝色/粉色背景及其他未被点击的Box,核心是通过**CSS滤镜(filter: blur())**给非目标元素添加模糊效果,同时配合JavaScript控制类的添加与移除,确保视觉焦点集中在被点击的Box上。

步骤1:添加模糊样式类

在CSS中新增模糊类,控制元素模糊效果的同时禁用其点击事件,避免干扰交互:

.blur {
  filter: blur(4px);
  pointer-events: none; /* 防止模糊元素拦截点击操作 */
  transition: filter 0.5s ease; /* 保持动画过渡流畅 */
}

.box {
  transition: transform 0.5s ease, filter 0.5s ease; /* 给Box添加滤镜过渡效果 */
}

步骤2:标记背景元素

修改foreignObjects数组,给蓝色、粉色背景的div添加统一类名background-element,方便后续批量选择操作:

const foreignObjects = [{
    x: 0,
    y: 0,
    width: "100%",
    height: "100%",
    content: '<div xmlns="http://www.w3.org/1999/xhtml" class="background-element"></div>',
    style: { backgroundColor: "blue" }
  },
  {
    x: 0,
    y: 0,
    width: 1200,
    height: 200,
    content: '<div class="background-element"></div>',
    style: { backgroundColor: "pink" }
  },
  {
    x: 0,
    y: 300,
    width: 1200,
    height: 200,
    content: '<div class="background-element"></div>',
    style: { backgroundColor: "pink" }
  },
  {
    x: 100,
    y: 0,
    width: 1000,
    height: 750,
    content: '<div class="container"></div>',
    style: {}
  }
];

步骤3:修改点击事件逻辑

在Box的点击事件中,添加模糊/取消模糊的控制逻辑,确保点击时只保留目标Box清晰:

div.addEventListener('click', () => {
  const backgroundElements = document.querySelectorAll('.background-element');
  const allBoxes = document.querySelectorAll('.box');

  // 先重置所有元素的模糊状态
  backgroundElements.forEach(el => el.classList.remove('blur'));
  allBoxes.forEach(box => box.classList.remove('blur'));

  // 处理之前点击的Box重置
  if (currentlyClickedBox && currentlyClickedBox !== div) {
    currentlyClickedBox.style.transform = 'none';
    currentlyClickedBox.style.position = "relative";
  }

  // 处理当前点击的Box:取消点击状态
  if (currentlyClickedBox === div) {
    currentlyClickedBox.style.transform = 'none';
    currentlyClickedBox.style.position = "relative";
    currentlyClickedBox = null;
  } else {
    const translateXValue = -div.getBoundingClientRect().x;
    const translateXOffset = (translateXValue + additionalXValue) - (offsetValue + parseInt(div.getAttribute('data-offset-additional')));

    currentlyClickedBox = div;
    div.style.transform = `translate(${translateXOffset}px, -350px) rotateY(180deg) scale(3)`;

    // 给背景元素和其他未点击的Box添加模糊
    backgroundElements.forEach(el => el.classList.add('blur'));
    allBoxes.forEach(box => {
      if (box !== div) box.classList.add('blur');
    });
  }
});

完整修改后代码

HTML

<svg id="mySvg" xmlns="http://www.w3.org/2000/svg" class="a p" viewBox="0 0 1200 800"></svg>

CSS

.a {
  height: 100vh;
  width: 100%;
}

div {
  width: 100%;
  height: 100%;
  background-size: contain;
  background-position: center;
  background-repeat: no-repeat;
}

.container {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  position: relative;
}

.box {
  transition: transform 0.5s ease, filter 0.5s ease;
}

.blur {
  filter: blur(4px);
  pointer-events: none;
  transition: filter 0.5s ease;
}

JavaScript

function applyStyles(element, styles) {
  for (const [key, value] of Object.entries(styles)) {
    element.style[key] = value;
  }
}

let currentlyClickedBox = null;

function renderBoxes(container) {
  let numberOfBoxes = boxes.length;
  let additionalXValue = 500 - (9 - numberOfBoxes) * 10;
  let offsetValue = 40;
  let offsetAdditional = 0;

  boxes.forEach(token => {
    const div = document.createElement('div');
    div.className = token.class;
    applyStyles(div, token.style);

    div.setAttribute('data-offset-additional', offsetAdditional);

    div.addEventListener('click', () => {
      const backgroundElements = document.querySelectorAll('.background-element');
      const allBoxes = document.querySelectorAll('.box');

      // 重置所有模糊状态
      backgroundElements.forEach(el => el.classList.remove('blur'));
      allBoxes.forEach(box => box.classList.remove('blur'));

      if (currentlyClickedBox && currentlyClickedBox !== div) {
        currentlyClickedBox.style.transform = 'none';
        currentlyClickedBox.style.position = "relative";
      }

      if (currentlyClickedBox === div) {
        currentlyClickedBox.style.transform = 'none';
        currentlyClickedBox.style.position = "relative";
        currentlyClickedBox = null;
      } else {
        const translateXValue = -div.getBoundingClientRect().x;
        const translateXOffset = (translateXValue + additionalXValue) - (offsetValue + parseInt(div.getAttribute('data-offset-additional')));

        currentlyClickedBox = div;
        div.style.transform = `translate(${translateXOffset}px, -350px) rotateY(180deg) scale(3)`;

        // 添加模糊效果
        backgroundElements.forEach(el => el.classList.add('blur'));
        allBoxes.forEach(box => {
          if (box !== div) box.classList.add('blur');
        });
      }
    });

    container.appendChild(div);
    offsetAdditional = offsetAdditional + 20;
  });
}

function renderForeignObjects() {
  const svg = document.getElementById('mySvg');

  foreignObjects.forEach(obj => {
    const foreignObject = document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject');
    foreignObject.setAttribute('x', obj.x);
    foreignObject.setAttribute('y', obj.y);
    foreignObject.setAttribute('width', obj.width);
    foreignObject.setAttribute('height', obj.height);

    const div = document.createElement('div');
    div.innerHTML = obj.content;
    applyStyles(div.firstChild, obj.style);

    if (div.firstChild && div.firstChild.classList.contains('container')) {
      renderBoxes(div.firstChild);
    }

    foreignObject.appendChild(div);
    svg.appendChild(foreignObject);
  });
}

const foreignObjects = [{
    x: 0,
    y: 0,
    width: "100%",
    height: "100%",
    content: '<div xmlns="http://www.w3.org/1999/xhtml" class="background-element"></div>',
    style: { backgroundColor: "blue" }
  },
  {
    x: 0,
    y: 0,
    width: 1200,
    height: 200,
    content: '<div class="background-element"></div>',
    style: { backgroundColor: "pink" }
  },
  {
    x: 0,
    y: 300,
    width: 1200,
    height: 200,
    content: '<div class="background-element"></div>',
    style: { backgroundColor: "pink" }
  },
  {
    x: 100,
    y: 0,
    width: 1000,
    height: 750,
    content: '<div class="container"></div>',
    style: {}
  }
];

const boxes = [{
    y: -50,
    class: "box",
    style: { width: "110px", height: "110px", margin: "0 5px", backgroundColor: "#ccc" }
  },
  {
    class: "box",
    style: { width: "110px", height: "110px", margin: "0 5px", backgroundColor: "#ddd" }
  },
  {
    class: "box",
    style: { width: "110px", height: "110px", margin: "0 5px", backgroundColor: "#ccc" }
  }
];

renderForeignObjects();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 12:39:51