具有不透明度的重叠元素并处理这些元素上的 'hover'
Overlapped elements with opacity and handling the 'hover' on those
这是一个 Q/A 关于如何处理重叠元素的不透明度并使其在悬停时保持一致的 JS 解决方案。
要求
需求是开发两个透明重叠的元素,如下图两个红框。这些需要是透明的,以便背景内容可见。
现在,将鼠标悬停在这些元素中的任何一个上时,特定元素应该变为不透明,如下所示。
解决方案
如要求中所述,解决方案首先创建两个元素,并可能对它们进行包装。
<div class="wrapper">
<div class="first"></div>
<div class="second"></div>
</div>
现在,我们设计它们以匹配设计。
.first,
.second {
width: 100px;
height: 100px;
background-color: red;
opacity: 0.6;
}
和下面的重叠代码行。
.second {
margin-left: 50px;
margin-top: -50px;
}
this approach 的问题是重叠区域的不透明度将不一致,并且会变得更暗。
请注意,这不是浏览器的错误,并且解释了此行为的原因 here。
正确的方法
处理这种情况的更好方法是避免使子元素透明,而是在父级别设置 'opacity'。悬停时,使用 JS 在父项和子项之间切换这些不透明度级别。
$(".first, .second").hover(function() {
$(".wrapper, .first, .second").not(this).toggleClass("add-opacity");
});
此外,悬停在重叠区域会由于堆叠顺序的变化而导致闪烁,这可以通过将悬停元素设置为z-index
来解决。
.first:hover,
.second:hover {
z-index: 1;
}
希望这对您有所帮助。
这是使用 Pointer_events
的另一种方法
每当您将鼠标悬停在一个元素上时,您就会禁用另一个元素上的 pointer-events
:
$('.first').hover(
() => { $('.second').css({'pointer-events': 'none'})},
() => { $('.second').css({'pointer-events': 'auto'})
})
$('.second').hover(
() => {$('.first').css({'pointer-events': 'none'})},
() => {$('.first').css({'pointer-events': 'auto'})
})
* {
box-sizing: border-box;
padding: 0;
margin: 0;
border: 0;
}
body {
background-image: linear-gradient(45deg, transparent 50%, #aaa 75%);
background-size: 20px 20px;
}
.wrapper {
margin-top: 10px;
margin-left: 10px;
}
.first {
width: 100px;
height: 100px;
background: rgba(255, 0, 0, 0.6);
}
.second {
width: 99px;
height: 98px;
margin-top: -49px;
margin-left: 50px;
background: -webkit-linear-gradient(transparent 50%, rgb(255, 0, 0) 50%), -webkit-linear-gradient(0deg, transparent 50%, rgb(255, 0, 0) 50%);
opacity: 0.6;
}
.first:hover,
.second:hover {
background: rgba(255, 0, 0, 1);
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div class="first" id="first"></div>
<div class="second" id="second"></div>
</div>
检查 compatibility 因为它可以在大多数浏览器中使用,除了 Safari(截至目前)。
只有 CSS 个解决方案,这使得它更有效。例如:
body {
background-image: linear-gradient(45deg, transparent 50%, #aaa 75%);
background-size: 20px 20px;
}
#a {
position: absolute;
width: 150px;
height: 150px;
top: 50px;
left: 50px;
background: rgba(255, 0, 0, 1);
}
#b {
position: absolute;
width: 150px;
height: 150px;
top: 125px;
left: 125px;
background: rgba(255, 0, 0, 1);
}
#wrapper {
opacity: 0.5;
}
/* instead of changing the classes,
you can use selectors like this:*/
#wrapper:hover #a:hover,
#wrapper:hover #b:hover {
opacity: 1;
z-index: 10;
}
#wrapper:hover {
opacity: 1;
}
#wrapper:hover #b,
#wrapper:hover #a {
opacity: 0.5;
z-index: -1;
}
<div id=wrapper>
<div id="a">
</div>
<div id="b">
</div>
</div>
我尝试使用绝对位置的元素。在这种情况下,我可以在鼠标进入时将它们中的每一个移动到 wrapper
的顶部,然后通过纯 JavaScript.
将它们移回鼠标离开时的位置
我已将示例扩展到 3 个元素,其中您的代码显示了工件,并添加了边框以实际看到重叠部分。
HTML:
<div id=top>
<div id=wrapper>
<div class="first" onMouseEnter="hover3b(event)" onMouseLeave="hover3e(event)"></div>
<div class="second" onMouseEnter="hover3b(event)" onMouseLeave="hover3e(event)"></div>
<div class="third" onMouseEnter="hover3b(event)" onMouseLeave="hover3e(event)"></div>
</div>
</div>
CSS:
body {
background-image: linear-gradient(45deg, transparent 50%, #aaa 75%);
background-size: 20px 20px;
}
.first, .second, .third {
width: 100px;
height: 100px;
background-color: red;
position: absolute;
border: 3px solid black;
}
#wrapper {
width: 200px;
height: 200px;
background-color: yellow;
border: 3px solid green;
opacity: 0.6;
}
.first { left: 0px; top: 0px; }
.second { left: 80px; top: 80px; }
.third { left: 160px; top: 160px; }
JavaScript:
var from = null; // remember where to put back the element
function hover3b(e) {
var t = e.target;
from = t.nextElementSibling;
if (!from)
from = null;
document.getElementById("top").appendChild(t);
}
function hover3e(e) {
document.getElementById("wrapper").insertBefore(e.target, from);
}
这是一个 Q/A 关于如何处理重叠元素的不透明度并使其在悬停时保持一致的 JS 解决方案。
要求
需求是开发两个透明重叠的元素,如下图两个红框。这些需要是透明的,以便背景内容可见。
现在,将鼠标悬停在这些元素中的任何一个上时,特定元素应该变为不透明,如下所示。
解决方案
如要求中所述,解决方案首先创建两个元素,并可能对它们进行包装。
<div class="wrapper">
<div class="first"></div>
<div class="second"></div>
</div>
现在,我们设计它们以匹配设计。
.first,
.second {
width: 100px;
height: 100px;
background-color: red;
opacity: 0.6;
}
和下面的重叠代码行。
.second {
margin-left: 50px;
margin-top: -50px;
}
this approach 的问题是重叠区域的不透明度将不一致,并且会变得更暗。
请注意,这不是浏览器的错误,并且解释了此行为的原因 here。
正确的方法
处理这种情况的更好方法是避免使子元素透明,而是在父级别设置 'opacity'。悬停时,使用 JS 在父项和子项之间切换这些不透明度级别。
$(".first, .second").hover(function() {
$(".wrapper, .first, .second").not(this).toggleClass("add-opacity");
});
此外,悬停在重叠区域会由于堆叠顺序的变化而导致闪烁,这可以通过将悬停元素设置为z-index
来解决。
.first:hover,
.second:hover {
z-index: 1;
}
希望这对您有所帮助。
这是使用 Pointer_events
的另一种方法每当您将鼠标悬停在一个元素上时,您就会禁用另一个元素上的 pointer-events
:
$('.first').hover(
() => { $('.second').css({'pointer-events': 'none'})},
() => { $('.second').css({'pointer-events': 'auto'})
})
$('.second').hover(
() => {$('.first').css({'pointer-events': 'none'})},
() => {$('.first').css({'pointer-events': 'auto'})
})
* {
box-sizing: border-box;
padding: 0;
margin: 0;
border: 0;
}
body {
background-image: linear-gradient(45deg, transparent 50%, #aaa 75%);
background-size: 20px 20px;
}
.wrapper {
margin-top: 10px;
margin-left: 10px;
}
.first {
width: 100px;
height: 100px;
background: rgba(255, 0, 0, 0.6);
}
.second {
width: 99px;
height: 98px;
margin-top: -49px;
margin-left: 50px;
background: -webkit-linear-gradient(transparent 50%, rgb(255, 0, 0) 50%), -webkit-linear-gradient(0deg, transparent 50%, rgb(255, 0, 0) 50%);
opacity: 0.6;
}
.first:hover,
.second:hover {
background: rgba(255, 0, 0, 1);
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div class="first" id="first"></div>
<div class="second" id="second"></div>
</div>
检查 compatibility 因为它可以在大多数浏览器中使用,除了 Safari(截至目前)。
只有 CSS 个解决方案,这使得它更有效。例如:
body {
background-image: linear-gradient(45deg, transparent 50%, #aaa 75%);
background-size: 20px 20px;
}
#a {
position: absolute;
width: 150px;
height: 150px;
top: 50px;
left: 50px;
background: rgba(255, 0, 0, 1);
}
#b {
position: absolute;
width: 150px;
height: 150px;
top: 125px;
left: 125px;
background: rgba(255, 0, 0, 1);
}
#wrapper {
opacity: 0.5;
}
/* instead of changing the classes,
you can use selectors like this:*/
#wrapper:hover #a:hover,
#wrapper:hover #b:hover {
opacity: 1;
z-index: 10;
}
#wrapper:hover {
opacity: 1;
}
#wrapper:hover #b,
#wrapper:hover #a {
opacity: 0.5;
z-index: -1;
}
<div id=wrapper>
<div id="a">
</div>
<div id="b">
</div>
</div>
我尝试使用绝对位置的元素。在这种情况下,我可以在鼠标进入时将它们中的每一个移动到 wrapper
的顶部,然后通过纯 JavaScript.
我已将示例扩展到 3 个元素,其中您的代码显示了工件,并添加了边框以实际看到重叠部分。
HTML:
<div id=top>
<div id=wrapper>
<div class="first" onMouseEnter="hover3b(event)" onMouseLeave="hover3e(event)"></div>
<div class="second" onMouseEnter="hover3b(event)" onMouseLeave="hover3e(event)"></div>
<div class="third" onMouseEnter="hover3b(event)" onMouseLeave="hover3e(event)"></div>
</div>
</div>
CSS:
body {
background-image: linear-gradient(45deg, transparent 50%, #aaa 75%);
background-size: 20px 20px;
}
.first, .second, .third {
width: 100px;
height: 100px;
background-color: red;
position: absolute;
border: 3px solid black;
}
#wrapper {
width: 200px;
height: 200px;
background-color: yellow;
border: 3px solid green;
opacity: 0.6;
}
.first { left: 0px; top: 0px; }
.second { left: 80px; top: 80px; }
.third { left: 160px; top: 160px; }
JavaScript:
var from = null; // remember where to put back the element
function hover3b(e) {
var t = e.target;
from = t.nextElementSibling;
if (!from)
from = null;
document.getElementById("top").appendChild(t);
}
function hover3e(e) {
document.getElementById("wrapper").insertBefore(e.target, from);
}