考虑一个简单的元素及其相关的CSS:
<div id="content">Hover me !</div>
#content {
width: 100px;
height: 100px;
}
#content:hover {
transform: translateY(500px);
transition: transform 1s 500ms;
}
原则是直截了当的:当元素悬停时,它必须下降。问题是,当鼠标移动时,即使元素不再在物理上低于鼠标(由于翻译),也会保持:hover
状态。只有在鼠标移动后,状态似乎才会更新。
注意光标(指针)及其与元素的相对位置!
只有在timeout
之后鼠标位于某个元素上时才必须执行JavaScript函数,这才是真正的问题:
// The mouseleave event will not be called during the transition,
// unless the mouse move !
element.on('mouseenter', executeAfterTimeout);
element.on('mouseleave', cancelTimeout);
所以这是我的问题:
编辑: 为了给你一个上下文,这是我想要具体做的事情:使用JavaScript,当鼠标位于元素上时,我会显示工具提示(和当鼠标离开时隐藏它)。但是当用户点击它时,相同的元素可以是transform
。如果用户只是在不移动鼠标的情况下单击,则工具提示将保持显示,这是一个真正的问题。如何检测元素消失?
答案 0 :(得分:7)
原则是直截了当的:当元素悬停时,它 必须下去。问题是,当鼠标不移动时,即 :即使元素实际上不在下面,也会保持悬停状态 鼠标了(由于翻译)。国家似乎是 只有在鼠标移动后才会更新。
所以这是我的问题:
- 这种行为是否正常(符合规范)?
醇>
是。这种行为很正常。虽然标准中没有逐字逐句指出,但在此处详细说明: http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105
将此小提琴作为参考:http://jsfiddle.net/Blackhole/h7tb9/3/
上部div
直接绑定了鼠标事件。较低的div
将鼠标事件绑定到其父级。拿起下面一个。在一个边缘缓慢移动鼠标并观察控制台以查看会发生什么。
mouseover
和mouseenter
会快速连续发起(悬停)。div
翻译。div
内。 mousemove
点火,内部div
仍然翻译。mouseout
和mouseleave
会快速连续发起,内部div
会转换回原来的位置。此处描述了鼠标事件订单部分下的 http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-mouseevents 。
上面的步骤3非常重要。因为你什么都不做,所以没有事件发生,因此没有任何反应。如果内部div
在此步骤中反弹回其原始位置,则意味着在没有任何事件的情况下发生了激活!
这与 event 的定义一致,作为本节中的文档:http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#glossary-event说:
事件是某些事件的表示(例如鼠标) 单击元素的表示,删除子节点 从一个元素,或任何数量的其他可能性) 与其事件目标相关联。每个事件都是一个实例 一种特定的事件类型。
现在看一下这里的文档: http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#event-flow ,就在第3.2节开始之前,它说:
事件完成其传播路径的所有阶段后,即 必须将Event.currentTarget设置为null并且必须设置Event.eventPhase 设置为0(无)。事件(或界面)的所有其他属性 派生自事件)不变(包括Event.target 属性,必须继续引用事件目标)。
最后一行(在括号中)很重要。即使在事件完成后,event.target仍继续引用事件目标。
现在选择小提琴中的上div
作为参考。在mouseenter
div
本身已翻译。 如果它远离鼠标指针下方并不重要。 event.target仍然引用它 ,如果没有其他鼠标事件发生,则没有任何反应,它仍然会被翻译。移动鼠标的时刻(无论进出),激活都发生在event.target(仍然是div
)和 上,现在用户代理发现鼠标指针是不再超过元素 并立即触发mouseout
和mouseleave
事件(当然在触发mousemove
之后)导致div
翻译回来。
2.避免此问题的解决方案是什么?
编辑:为了给你一个上下文,这是我想要具体做的事情: 使用JavaScript,当鼠标位于元素上时,我会显示工具提示 (并在鼠标离开时隐藏它)。但是相同的元素可以 用户点击它时转换。如果用户只需点击 不移动鼠标,工具提示将保持显示,即 一个真正的问题。如何检测元素消失?
如果你看一下这个小提琴中div
下面的实现:http://jsfiddle.net/abhitalks/h7tb9/2/;与上部div相比,当鼠标移动时没有颤动/抖动。这是因为而不是div
本身,事件正在父母处理。
因此,这可能是您用例的一种解决方案。
查看此演示:http://jsfiddle.net/Blackhole/nR8t9/9/
这解决了您的编辑问题。工具提示显示在mouseover
上。工具提示隐藏在mouseleave
上。 click
时,可以转换相同的元素。如果您只是click
而没有移动鼠标,则工具提示会隐藏。
此处,如果您click
,正在翻译该元素,则不会再发生hover
次操作。工具提示本身使用:before
伪元素实现。这会将工具提示和要在click
之后更改的元素分开。您仍然可以处理元素本身的事件。不需要超时,因为它由css本身处理。如果您mouseout
,工具提示会在延迟后隐藏。
希望有所帮助。
答案 1 :(得分:2)
这是一个使用JavaScript和类来指示状态的解决方案。在您的情况下,您可以使用mouseover
事件来切换这样的类:
$('#content').on('mouseover', function() {
$(this).toggleClass('down');
});
CSS
#content.down {
background-color: deepskyblue;
transform:translateY(300px);
-webkit-transform: translateY(300px);
}
另一种解决方案是使用包装器作为悬停块
<div id="container">
<div id="wrapper">
<div id="content">Hover me !</div>
</div>
</div>
CSS
#wrapper:hover #content {
background-color: deepskyblue;
transform:translateY(300px);
-webkit-transform: translateY(300px);
}
请注意,这两种解决方案针对不同的要求有不同的行为。
答案 2 :(得分:2)
我的建议是以另一种方式来看待这个问题:如果一个元素在你click
时转换。为什么不在click
而不是mouseleave
上执行回调?
我假设工具提示与您mouseenter
的元素有一些连接,在这种情况下mouseleave
和click
实际上是相同的 - 它们都会导致鼠标指针不在元素不再(无论浏览器的行为如何)。
PS:请注意,在您的示例中,mouseenter
和mouseleave
如何触发还取决于您是将transition
设置为默认属性还是:hover
状态属性,因为这看起来像浏览器供应商可以随意优化的区域,所以你应该首先避开它们。
transition on #content:hover
transition on #content
答案 3 :(得分:1)
此行为是正常的,以防止元素在光标下弹跳。想象一下,只要元素远离光标,转换就会恢复。一旦光标离开元素,它就会返回,因此光标再次位于元素上方并向下移动。这样它就会在光标的边缘上下跳动。
一种解决方案是使用JavaScript而不是CSS实现转换,然后该元素将反弹&#34;。但这真的是理想的行为吗?你究竟想做什么?
答案 4 :(得分:1)
此行为是正常的,无法更改。它是根据链接到的the specification @ Stasik正确实现的。
如果必须更改此行为,可以使用javascript而不是css伪类。我创建了一个jsfiddle来演示使用@ Ivan Castellanos here提供的.ismouseover()
jQuery扩展程序的可能方法。
答案 5 :(得分:0)
检查这是否是您要完成的行为。有些是示例样式,可随意调整。
.tooltip {
background-color: white;
border: 1px solid black;
padding: 10px;
opacity: 0;
transition: 1s 500ms;
transition-property: transform, opacity;
position: absolute;
right: 0;
top: 0;
}
#content:hover .tooltip {
display: block;
opacity: 1;
transform:translateX(100px);
-webkit-transform: translateX(100px);
}
#content {
transition: 1s 500ms;
transition-property: background-color, color;
cursor: pointer;
position: relative;
}
#content.active {
background-color: blue;
color: white;
}
#content.active .tooltip {
opacity: 0;
transform: none;
-webkit-transform: none;
}
我已添加此javascript代码段来控制点击状态
$('#content').click(function () {
$(this).toggleClass('active');
});