zerolab-fe / one-question-per-day

每天一个小问题
21 stars 7 forks source link

快速滑动导致 mouseLeave 不触发问题 #111

Open GleanCoder1116 opened 3 years ago

GleanCoder1116 commented 3 years ago

在快速滑动鼠标的时候,会出现绑定在DOM元素上的mouseLeave事件不可触发; 刚开始个人认为是我写的代码问题;或者react这个库的问题;但是在一个完全干净的html中也会出现该情况;

现象

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<style>
    div {
        height: 100px;
        width:300px;
    }
</style>
<body>
   <div id='root' onmouseleave="leave()" style="height: 200px"></div>

</body>
<script>
    ['red', 'green'].forEach(function (c) {
        var div = document.createElement('div')
        div.style.backgroundColor = c
        document.querySelector('#root').appendChild(div)
        div.addEventListener('click', function (e) {
            e.target.parentNode.removeChild(e.target)
        })
        div.addEventListener('mouseenter', function (e) {
            console.log('enter ' + e.target.style.backgroundColor)
            e.target.parentNode.removeChild(e.target)
        })
        div.addEventListener('mouseleave', function (e) {
            console.log('leave ' + e.target.style.backgroundColor)
            e.target.parentNode.removeChild(e.target)
        })
    })
    function leave() {
        console.log('leave++++')
    }
</script>
</html>

在以上代码中快速滑动就会出现,未触发 父级 onmouseleave 的现象; 现象如下: image

原因

自己在chromium的issue中找到了相关解释

有心的可以自己看一下;或者继续寻找答案;或者看我个人的理解,按照我的理解确实没有再出现高速滑动,leave未触发的情况

原因如下: 我就不按照,react中自己写的代码解释了,那个更复杂;以上面代码为例,当你滑动到 root包裹的两个div的时候,会发现他们消失了。在mouse一些列方法中;w3c有这样的一个规定,mouse方法中有个附属信息,该附属信息是包含你的鼠标上一个滑动的元素或者节点信息;如果该附属信息中没有节点信息,及浏览器认为他是从外部划入的;是一次无效的滑动;上面的两个issue链接有提到;这个也未触发mouseLeave的原因;我按照这个问题去避免划过元素消失;确实解决了这个问题;但是我还是持怀疑态度的,继续寻找答案