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

如何实现一个Div在另一Div对应位置的透明效果?

实现指定Div区域内另一Div的透明效果(原生JS方案)

你遇到的问题核心是:用一个Div定义透明区域,让第二个Div在该区域内透明,同时第三个Div位置变化时效果不失效——clip-path因为是固定在目标Div上的静态路径,确实没法适配动态位置的变化,换用CSS mask + 原生JS动态计算的方案就能解决。

实现思路

通过原生JS实时获取第三个动态Div的位置和尺寸,同步更新“透明定义Div”的位置,再用CSS mask属性给第二个Div设置局部透明区域。mask支持动态更新坐标,能完美适配第三个Div的位置变化。

完整代码示例

HTML结构

<div class="container">
  <div class="bg-div"></div> <!-- 需要局部透明的背景Div -->
  <div class="transparent-define-div"></div> <!-- 透明区域定义Div(仅占位,不显示) -->
  <div class="dynamic-div"></div> <!-- 位置会动态变化的Div -->
</div>

基础CSS样式

.container {
  position: relative;
  width: 800px;
  height: 600px;
  overflow: hidden;
  border: 1px solid #eee;
}

.bg-div {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: #3498db; /* 示例背景色,可替换 */
}

.transparent-define-div {
  position: absolute;
  opacity: 0; /* 隐藏,仅用来标记区域 */
  pointer-events: none; /* 不干扰交互 */
}

.dynamic-div {
  position: absolute;
  top: 150px;
  left: 150px;
  width: 150px;
  height: 150px;
  background: #e74c3c;
  cursor: move; /* 方便测试拖动 */
}

原生JS逻辑

const bgDiv = document.querySelector('.bg-div');
const dynamicDiv = document.querySelector('.dynamic-div');
const transparentDefineDiv = document.querySelector('.transparent-define-div');
const container = document.querySelector('.container');

// 更新透明遮罩的核心函数
function updateTransparentArea() {
  // 获取动态Div在容器内的相对位置和尺寸
  const containerRect = container.getBoundingClientRect();
  const dynamicRect = dynamicDiv.getBoundingClientRect();
  
  const relX = dynamicRect.left - containerRect.left;
  const relY = dynamicRect.top - containerRect.top;
  const { width, height } = dynamicRect;

  // 同步更新透明定义Div的位置
  transparentDefineDiv.style.left = `${relX}px`;
  transparentDefineDiv.style.top = `${relY}px`;
  transparentDefineDiv.style.width = `${width}px`;
  transparentDefineDiv.style.height = `${height}px`;

  // 设置CSS mask:仅动态Div覆盖的区域透明,其余部分不透明
  const maskStyle = `
    linear-gradient(#fff, #fff) ${relX}px ${relY}px / ${width}px ${height}px no-repeat,
    linear-gradient(#fff, #fff)
  `;
  bgDiv.style.mask = maskStyle;
  bgDiv.style.webkitMask = maskStyle; // 兼容webkit内核浏览器
}

// 初始化时执行一次
updateTransparentArea();

// 监听动态Div的拖动事件
let isDragging = false;
let startPos = { x: 0, y: 0 };
let initialPos = { x: 0, y: 0 };

dynamicDiv.addEventListener('mousedown', (e) => {
  isDragging = true;
  startPos.x = e.clientX;
  startPos.y = e.clientY;
  initialPos.x = parseInt(window.getComputedStyle(dynamicDiv).left);
  initialPos.y = parseInt(window.getComputedStyle(dynamicDiv).top);
});

document.addEventListener('mousemove', (e) => {
  if (!isDragging) return;
  const dx = e.clientX - startPos.x;
  const dy = e.clientY - startPos.y;
  dynamicDiv.style.left = `${initialPos.x + dx}px`;
  dynamicDiv.style.top = `${initialPos.y + dy}px`;
  // 实时更新遮罩
  updateTransparentArea();
});

document.addEventListener('mouseup', () => {
  isDragging = false;
});

// 监听动态Div的style变化(比如JS修改、动画),自动更新遮罩
const observer = new MutationObserver(updateTransparentArea);
observer.observe(dynamicDiv, { attributes: true, attributeFilter: ['style'] });

方案优势

  1. 动态适配:不管第三个Div是拖动、JS修改还是动画改变位置,都会实时更新透明区域,不会失效
  2. 原生实现:完全用Vanilla JS和CSS实现,不需要任何框架依赖
  3. 性能友好:仅在位置变化时更新计算,不会造成不必要的性能消耗

内容的提问来源于stack exchange,提问作者Oříšek

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 11:23:33