如何实现一个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'] });
方案优势
- 动态适配:不管第三个Div是拖动、JS修改还是动画改变位置,都会实时更新透明区域,不会失效
- 原生实现:完全用Vanilla JS和CSS实现,不需要任何框架依赖
- 性能友好:仅在位置变化时更新计算,不会造成不必要的性能消耗
内容的提问来源于stack exchange,提问作者Oříšek
相关产品推荐
相关产品推荐

