【问题标题】:Overlapped elements with opacity and handling the 'hover' on those具有不透明度的重叠元素并处理这些元素上的“悬停”
【发布时间】:2018-09-28 18:12:15
【问题描述】:

这是一个关于如何使用 JS 解决方案处理重叠元素的不透明度并使其在悬停时保持一致的 Q/A。

要求

要求是开发两个元素,透明重叠,如下图两个红框。这些需要是透明的,以便背景内容可见。

现在,当将鼠标悬停在任何这些元素上时,特定元素应该变成不透明的,如下所示。

【问题讨论】:

  • 我认为悬停部分在这里不太相关。
  • @appleapple - 你为什么这么认为?至少,这是要求的一部分:)
  • 好吧,如果你能做到第一个,我想第二个很简单。
  • 感谢这个有趣的问题,无论如何。
  • @appleapple - 确实如此 :) 只是节省了人们推导逻辑的时间。

标签: javascript jquery html css opacity


【解决方案1】:

有一个纯 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>

【讨论】:

  • 只有css会很棒,你知道如何让它们透明吗?
  • @Scaramouche 不确定您的意思,它们在示例中是透明的。我添加了背景以使其更加明显。
  • 太棒了。我不知道那些有多个 hover 的选择器。
  • 使用此解决方案,您仍然可以在其他元素的交叉点上获得额外的不透明度,例如here。而且它不是 JS。
【解决方案2】:

我尝试使用绝对位置的元素。在这种情况下,我可以通过纯 JavaScript 在鼠标输入时将它们中的每一个移动到 wrapper 的顶部,然后在鼠标离开时回到它们的位置。

我已将示例扩展为 3 个元素,您的代码在其中显示了工件,并添加了边框以实际看到重叠。

CODEPEN

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);
}

【讨论】:

  • 这也是一个有效的解决方案。感谢您的努力。
【解决方案3】:

解决方案

如需求中所述,解决方案首先创建两个元素,并且可能是这些元素的包装器。

<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 中解释。


正确的方法

处理这种情况的更好方法是避免使子元素透明,而是在父级别设置“不透明度”。并且在悬停时,使用 JS 在父级和子级之间切换这些不透明度级别。

$(".first, .second").hover(function() {
  $(".wrapper, .first, .second").not(this).toggleClass("add-opacity");
});

另外,重叠区域的悬停会因为堆栈顺序的变化而导致闪烁,可以通过将z-index设置为悬停元素来处理。

.first:hover,
.second:hover {
  z-index: 1;
}

CODEPEN

希望这会有所帮助。

【讨论】:

  • 你为什么要为你的问题创建一个赏金然后自己回答?
  • 想知道有没有更好的答案。
  • “希望这会有所帮助。”做到了吗?
  • @JorgeZuverza,我不确定你的意思。
  • @JPeG,仅供参考,我上周已经回答了这个问题,但是昨天创建了赏金,看看是否有更好的解决方案。上面还有一些其他用户发布的内容。
【解决方案4】:

这是使用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 之外的大多数浏览器(截至目前)。

【讨论】:

  • 这仍然不能解决重叠区域的不透明度不一致问题。请查看我的回答,了解如何处理。
猜你喜欢
  • 2014-12-19
  • 2016-07-04
  • 1970-01-01
  • 1970-01-01
  • 2021-12-28
  • 1970-01-01
  • 2013-06-03
  • 2018-12-24
相关资源
最近更新 更多