问题描述
MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports) OS: 10.14.5 (18F132)
Chrome: 79.0.3945.88
<div class="hover">
test
</div>
.hover:hover {
color: blue;
}
鼠标移动在该div元素上,点击后通过js移动此元素至别处,使鼠标不再hover,此时该div仍然保持了原来的hover state,当鼠标再次被用户移动时hover效果才会消失。
大胆猜测
css的hover触发可能是通过MouseEvent(MouseOver)事件触发的,在浏览器的事件机制实现上存在(ReadOnly)isTrusted属性:event.isTrusted,在由用户自身鼠标操作生成的事件此属性为true,由script自行dispatch的此属性为false。
大胆猜测hover效果的保持是因为元素移动是由脚本自行触发的,从而事件的isTrusted为false,从而没有触发hover的移除效果。
小心求证
this.$el.querySelector('.hover').addEventListener('mouseover', evt => {
console.log('hovering', evt);
});
this.$el.querySelector('.hover').addEventListener('mouseenter', evt => {
console.log('mouseenter', evt);
});
this.$el.querySelector('.hover').addEventListener('mouseleave', evt => {
console.log('mouseleave', evt);
});
this.$el.querySelector('.hover').addEventListener('mouseout', evt => {
console.log('mouseout', evt);
});
通过给该元素添加对应的鼠标事件可以发现触发顺序为:over->enter->out->leave
点击该元素使其移动时发现只触发了over->enter事件,其他两个事件等自己移动鼠标时才触发…
猜测暂时无法证实—根本就没有触发mouseout和mouseleave事件…
解决办法
想到了一个比较hack的解决方案:点击事件的同时给元素添加一个动画:
@keyframes recoverMouseEvt {
0% {
pointer-events: none;
}
100% {
pointer-events: initial;
}
}
动画开始时候移除鼠标事件,从而使hover效果消失,在动画结束之后再恢复鼠标事件。
遗留问题
FireFox上这个还是不好使–