为什么 setTimeout 没有按预期工作?

Why doesn't setTimeout work as expected?

每次我的鼠标指针悬停在 <div id="box"> 上时,我都试图移动它,但它似乎只有在 div 上有 mouseover 事件时才会移动,而不是当我的鼠标悬停在它上面时。

document.getElementsByTagName("body")[0].addEventListener("load",init());

function init(){
 console.log('in init');
 document.getElementById("box").addEventListener("mouseover",function(){
    var pixels=5;
    var perMs=40;
    var repeater=setTimeout(moveBox(pixels),perMs);

    document.getElementById("box").addEventListener("mouseout",function(){
        console.log('mouseOut');
        clearTimeout(repeater);
        });

    });

 }

 function moveBox(pixels){

    console.log('moveBox');
    var leftBox=document.getElementById("box").style.left;
    leftBox=parseInt(leftBox)+pixels;
    document.getElementById("box").style.left=leftBox;

  }

您的代码中存在许多语法问题,此处已更正主要问题。

function init() {
    console.log('in init');
    var box = document.getElementById("box"),
        pixels = 5,
        perMs = 40,
        repeater;

    function moveBox(pixels) {
        console.log('moveBox', pixels);
        var boxLeft = parseInt(box.style.left, 10) || 0;
        box.style.left = (boxLeft + pixels) + 'px';
    }

    box.addEventListener("mouseover", function() {
        repeater = setTimeout(moveBox, perMs, pixels);
    });

    box.addEventListener("mouseout", function(){
        console.log('mouseOut');
        clearTimeout(repeater);
    });

}

document.getElementsByTagName("body")[0].addEventListener("load",init);

请注意setTimeout只调用一次,不会重复。

此处演示:https://jsfiddle.net/vqgesj58/1/

如果你想让你的盒子在鼠标悬停时移动,我会更新代码。

您似乎打算使用 setInterval 来重复调整元素:

var repeaterId = setInterval(moveBox, perMs, pixels);

了解更多信息 here

setTimeout 收到一个回调函数作为第一个参数,问题是 moveBox(pixels) 执行函数并且 returns 它是结果所以你应该把它包装到另一个函数中。

此外,每次在鼠标悬停回调中订阅时,您都希望取消订阅 'mouseout' 事件:

function init(){
 console.log('in init');
 document.getElementById("box").addEventListener("mouseover",function(){
    var pixels=5;
    var perMs=40;
    var repeater=setTimeout(function(){moveBox(pixels)},perMs);



    document.getElementById("box").addEventListener("mouseout",function onMouseOut(){
        console.log('mouseOut');
        clearTimeout(repeater);
        document.getElementById("box").removeEventListener("mouseout",onMouseOut);
        });

    });


 }