3

我有一个元素,我称之为back被另一个元素覆盖front

Back在 CSS 中设置以在悬停时更改颜色。Front设置为,当悬停时,1s延迟后消失,并且元素上的鼠标指针Front现在位于后元素上。

Frontheight: 0通过在 JavaScript 中设置消失。消失后Front鼠标指针悬停在Back浏览器上不会重新渲染悬停效果Back,导致其颜色没有按应有的方式更改。

当我通过自然地Front从 DOM 中删除来尝试相同的示例时,它可以正常工作。但是,我的应用程序需要我通过设置height: 0.

您可以在以下示例中亲自尝试。您将看到一个红色框和一个蓝色框。红色是Front,蓝色是Back。当您将鼠标指针移至红色框时,红色框的颜色变为green。当您将鼠标移到蓝色框上时,一秒钟后,它会消失。

该示例的重点是表明在蓝色框消失后,鼠标指针现在悬停在红色框上,因此应该变为green

这个例子中,蓝色的盒子完全从 DOM 中移除,它的工作和预期的一样好。

但是,在此示例中,蓝色框将通过设置 删除height: 0green消失后,红色元素直到我移动鼠标后才会变为。

有没有办法强制浏览器重新渲染?

该问题在 Google Chrome 和 Microsoft Edge 中仍然存在。火狐很好用。

4

5 回答 5

6

而不是试图强制浏览器重新渲染,你可以添加一个类foo,当它消失时它会变成绿色bar,然后,它会在mouseleave.

CSS

#foo.hover, /* <- I just added this */
#foo:hover {
    background-color: green;
}

JavaScript

var
  foo = document.getElementById("foo"),
  bar = document.getElementById("bar");

/* Set the 'mouseenter' event for bar to set the height to 0 and & the 'hover' class. */
bar.onmouseenter = function() {
  setTimeout(function() {
    bar.style.height = 0;
    foo.classList.add("hover");
  }, 1000);
}

/* Set the 'mouseleave' event for bar to remove the 'hover' class. */
bar.onmouseleave = function() {
  foo.classList.remove("hover");
}

查看以下代码片段以获得视觉表示。

片段:

/* --- JavaScript --- */
var
  foo = document.getElementById("foo"),
  bar = document.getElementById("bar");

/* Set the 'mouseenter' event for bar. */
bar.onmouseenter = function() {
  setTimeout(function() {
    /* Set the height to 0. */
    bar.style.height = 0;
    
    /* Add the 'hover' class. */
    foo.classList.add("hover");
  }, 1000);
}

/* Set the 'mouseleave' event for bar. */
bar.onmouseleave = function() {
  /* Remove the 'hover' class. */
  foo.classList.remove("hover");
}
/* --- CSS --- */
#foo {
  width: 200px;
  height: 200px;
  background-color: red;
  position: absolute;
  top: 10px;
  left: 15px;
}
#foo.hover,
#foo:hover {
  background-color: green;
}
#bar {
  width: 200px;
  height: 200px;
  background-color: blue;
  position: absolute;
  top: 100px;
  left: 100px;
}
<!-- HTML -->
<div id = "foo"></div>
<div id = "bar"></div>

于 2016-07-17T13:27:50.710 回答
4

这似乎真的是一个浏览器问题,有一些方法可以强制 webkit 重绘。但我真的不建议你这样做。您可以简单地使用bar.style.display = 'none';而不是将高度设置为零。具有相同的效果,一切都按预期工作。看到这个小提琴:https ://jsfiddle.net/zkhorh38/4/ 。

于 2016-07-10T10:38:28.737 回答
3

transition只需使用属性就可以在 CSS 中做到这一点。

#foo {
  width: 200px;
  height: 200px;
  background-color:red;
  position: absolute;
  top:10px;
  left:15px;
  z-index: 10;
}

#foo:hover {
  background-color: green;
}

#bar {
  width: 200px;
  height: 200px;
  background-color:blue;
  position: absolute;
  top:100px;
  left:100px;
  z-index: 20;
  
  transition: all 1000000s; 
}

#bar:hover {
  transition: all 0.01s;
  opacity: 0;
  z-index: 1;
}
<div id="foo"></div>
<div id="bar"></div>

于 2016-07-21T11:40:02.593 回答
1

如果back完全被front覆盖,可以先在回调中设置让鼠标在front消失之前激活back的规则。front.style['pointer-events'] = 'none'onmouseenter:hover

请参阅修改后的工作片段

于 2016-07-23T18:57:43.907 回答
1

这可能是浏览器问题,但有一些方法可以强制 webkit 重绘。但我不建议你这样做。您可以简单地使用bar.style.display = 'none';而不是将高度设置为零。

另一种强制重绘/重绘的解决方案可以正常工作:

sel.style.display='none';
sel.offsetHeight; // no need to store this anywhere, the reference is enough
sel.style.display='';

**

为避免闪烁,您可以尝试'inline-block','table''run-in'代替'none',但这可能会产生副作用。此外,超时 0 会触发重排,就像查询 offsetHeight 一样:sel.style.display = 'run-in'; setTimeout(function () { sel.style.display = 'block'; }, 0);

试试这个真的很管用!

于 2016-07-21T17:39:47.237 回答