即使元素已经消失,在转换期间也会保持悬停状态

 互相体谅知足常乐 发布于 2023-01-17 10:20

考虑一个简单的元素及其相关的CSS:

Hover me !
#content {
    width: 100px;
    height: 100px;
}

#content:hover {
    transform: translateY(500px);
    transition: transform 1s 500ms;
}

JSFiddle

原则是直截了当的:当元素悬停时,它必须下降.问题是,当鼠标不移动时,:hover即使元素不再在物理上低于鼠标(由于翻译),状态也会保持不变.只有在鼠标移动后才会更新状态.

问题的插图
注意光标(指针)及其与元素的相对位置!

当一个JavaScript函数必须仅在鼠标位于元素上时执行时,这是一个真正的问题timeout:

// The mouseleave event will not be called during the transition,
// unless the mouse move !

element.on('mouseenter', executeAfterTimeout);
element.on('mouseleave', cancelTimeout);

所以这是我的问题:

    这种行为是否正常(符合规范)?

    有哪些解决方案可以避免这个问题?

编辑:为了给你一个上下文,这是我想要具体做的事情:使用JavaScript,当鼠标在元素上时显示工具提示(并在鼠标离开时隐藏它).但是transform当用户点击它时,可以使用相同的元素.如果用户只是在不移动鼠标的情况下单击,则工具提示将保持显示,这是一个真正的问题.如何检测元素消失?

1 个回答
  • 问题的第1部分:

    原则是直截了当的:当元素悬停时,它必须下降.问题是,当鼠标不移动时,即使元素不再在物理上低于鼠标(由于转换),也会保持:悬停状态.只有在鼠标移动后才会更新状态.

    所以这是我的问题:

      这种行为是否正常(符合规范)?

    是.这种行为很正常.虽然标准中没有逐字说明,但在此详细说明:http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105

    把这个小提琴作为参考:http://jsfiddle.net/Blackhole/h7tb9/3/

    上面div有直接绑定它的鼠标事件.较低的div鼠标事件绑定到其父级.拿起下面一个.在一个边缘缓慢移动鼠标并观察控制台以查看会发生什么.

      你触摸边缘,mouseovermouseenter快速连续地(悬停)被解雇.

      结果,内在div翻译.

      没做什么.没有事件被触发,所以没有任何反应.

      将鼠标移到外部div.mousemove火灾和内在div仍然翻译.

      慢慢移开鼠标.mouseout并且mouseleave快速连续发射,内部div转换回原来的位置.

    这里描述了:http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-mouseevents下的鼠标事件顺序部分.

    上面的步骤3很重要.因为你什么都不做,所以没有事件发生,因此没有任何反应.如果内部div在此步骤中反弹回其原始位置,则意味着在没有任何事件的情况下发生了激活!

    这与事件的定义一致,如本节中的文档: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(NONE).Event的所有其他属性(或从Event派生的接口)都保持不变(包括Event.target属性,该属性必须继续引用事件目标).

    最后一行(括号中)很重要.即使事件完成,event.target仍继续引用事件目标.

    现在选择div小提琴中的鞋面作为参考.在mouseenterdiv自己被翻译.它是否远离鼠标指针下方无关紧要.event.target仍然引用它,如果没有其他鼠标事件发生,则没有任何反应,它仍然被翻译.那一刻您移动鼠标(任何地方或缩小),激活发生在event.target(这仍然是这个div)和现在的用户代理发现鼠标指针不再是在元素并立即mouseoutmouseleave事件触发(在射击之后mousemove)导致div翻译回来.

    你问题的第2部分:

    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,工具提示会在延迟后隐藏.

    希望有所帮助.

    2023-01-17 10:24 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有