注意:我会将 overlay 一词与 backdrop 互换使用。
我目前正在制作指南模式,并突出显示元素,使它们从较暗的半透明背景中脱颖而出。
所以基本上,我有一个我想要不覆盖的元素的选择器,然后用半透明的黑暗div来包围它,模拟带有排除元素的叠加。
我的解决方案适用于一个突出显示的元素,但当该数字变为2+时,很难计算如何将黑色div放在这些元素周围。事情是:突出显示的需求会因页面而异 - 这并不像那些多个元素是静态的。
为了说明我的问题:
在这里你可以看到需要放入页面的不同盒子,以便用半透明的黑暗div来包围Box2和Box2,基本上用突出显示的元素模拟叠加效果。对于像这样的一个案例,我可以硬编码计算,一切都会好的,但如果 Box1比Box2高?那么如果他们不再水平重叠呢?如果Box3需要突出显示怎么办?
在任何一种情况下,我都不知道要放置多少个暗盒以及放置它们的位置。
在这种情况下,是否有任何数学公式可以帮助我?使用jQuery也是可能的,因为它包含在我的项目中。
我如何解决这个问题并使其可扩展(多个框,不同的位置)?
答案 0 :(得分:9)
你过度思考! 您正在寻找的是使用某种HTML和CSS布局。
您必须使用与此类似的布局:
.container
.overlay
.box
.box
.box
.box
诀窍是使用全宽,半透明覆盖并将需要突出显示的元素添加到前面。非常重要的是将pointer-events: none
指定给叠加层,以便点击它!
让.box
的{{1}}值为z-index
,而1
的{{1}}值为.overlay
。要突出显示某个z-index
,请将其100
设置为.box
。这样它就会突出显示。
我现在正在移动设备上,但我在 Codepen 上放了一个基本的概念验证。单击框以突出显示它们,再次单击以撤消。使用多个盒子!
答案 1 :(得分:1)
您可以使用阴影更轻松地解决此问题。
然后,您只需要将屏幕分为两部分
body, html {
height: 100%;
}
body {
background-image: linear-gradient(45deg, yellow, tomato);
}
.mask {
overflow: hidden;
width: 50%;
height: 100%;
display: inline-block;
position: relative;
}
#mask1 {
left: 0px;
}
#mask2 {
right: 0px;
}
.hole {
width: 150px;
height: 90px;
position: absolute;
box-shadow: 0px 0px 0px 2000px rgba(0,0,0,0.5);
}
#mask1 .hole {
left: 40px;
top: 40px;
}
#mask2 .hole {
left: 140px;
top: 20px;
}

<div class="mask" id="mask1">
<div class="hole"></div>
</div><div class="mask" id="mask2">
<div class="hole"></div>
</div>
&#13;
答案 2 :(得分:1)
考虑使用区域
虽然这里有很多好的答案,你可能想考虑移动@WearyAdventurer提出的元素,其他答案都没有真正解决原来的问题:
如何以一种看似包围其他元素的方式创建元素?
使用名为 Region 的数据类型可以最好地解决该问题的答案。区域允许您使用2-D屏幕空间块轻松执行设置操作:将此区域与 区域组合,然后减去另一个区域,然后将结果转换为我可以渲染的一组矩形。区域存在于大多数窗口系统(MS Windows,X Windows,经典MacOS等)中,并且在大多数浏览器中被大量使用&#39;用于渲染元素的内部机制,但它们在JavaScript中令人惊讶地缺席。
或者在我写一个图书馆之前,他们一直缺席。
区域的基本逻辑有些复杂。有许多极端情况,处理可能出现的所有情况可能具有挑战性。我的实现Region2D使用不相交的行(带)不相交的矩形(1维区域),这与许多X Windows服务器的行为相同。其他实现使用空间分区算法,还有一些(如现代MacOS)使用路径或多边形渲染技术而不是区域。
基本理念
无论您使用哪种实施方式,基本理念都保持不变。在您的情况下,您从一个覆盖屏幕的大矩形开始,然后简单地减去您想要的两个(或三个,或四个或其他)矩形,然后询问区域这些操作产生的矩形。在JavaScript中,使用我的Region2D库,它看起来像这样:
var screenRegion = new Region([0, 0, viewportWidth, viewportHeight]);
var elemRegion1 = new Region(element1);
var elemRegion2 = new Region(element2);
var coverRegion = screenRegion.subtract(elemRegion1).subtract(elemRegion2);
var coverRectangles = coverRegion.getRects();
生成的矩形数组是具有x
/ y
/ width
/ height
/ top
/ left
/ {的简单对象{1}} / right
坐标,因此您只需从每个元素中创建bottom
元素,即可完成。
工作实施
所以这里是一个解决实际问题的解决方案,使用我的Region2D库来进行繁重的算法提升:
<div>
&#13;
// Generate regions for each of the objects.
var containerRegion = new Region2D($(".container")[0]);
var target1Region = new Region2D($(".target1")[0]);
var target2Region = new Region2D($(".target2")[0]);
// Subtract the targets from the container, and make an array of rectangles from it.
var coverRegion = containerRegion.subtract(target1Region).subtract(target2Region);
var coverRects = coverRegion.getRects();
// Create gray <div> elements for each rectangle.
for (var i = 0, l = coverRects.length; i < l; i++) {
var coverRect = coverRects[i];
var coverElement = $("<div class='cover'>");
coverElement.css({
left: (coverRect.x - 1) + "px", top: (coverRect.y - 1) + "px",
width: coverRect.width + "px", height: coverRect.height + "px"
});
coverElement.appendTo($(".container"));
}
&#13;
.container, .target1, .target2, .cover { position: absolute; top: 0; left: 0; box-sizing: border-box; }
.target1, .target2 { border: 1px solid red; }
.container { width: 330px; height: 230px; border: 1px solid blue; }
.target1 { top: 40px; left: 40px; width: 100px; height: 80px; }
.target2 { top: 100px; left: 180px; width: 100px; height: 80px; }
.cover { background: rgba(0, 0, 0, 0.5); border: 1px solid #000; }
&#13;