V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
manyfreebug
V2EX  ›  JavaScript

已经使用 clearInterval() ,为什么还是无法清除定时器?

  •  
  •   manyfreebug · 2019-05-02 12:37:37 +08:00 · 11046 次点击
    这是一个创建于 2019 天前的主题,其中的信息可能已经有所发展或是发生改变。
    代码及运行效果均可在 jsbin 中查看:
    https://jsbin.com/waduqigayo/1/edit?html,css,js,console,output
    
    15 条回复    2019-05-03 00:59:32 +08:00
    Lax
        1
    Lax  
       2019-05-02 12:57:58 +08:00
    mouseover 调用了几次?
    Oceanhime
        2
    Oceanhime  
       2019-05-02 13:00:27 +08:00   ❤️ 1
    在 timer = setInterval(function(){...}) 这里, 如果不加 var, 则 timer 是一个成员变量, 只在当前的匿名函数中有效。
    解决方法是更改为 var timer = setInterval(function(){...}) 。
    ace12
        3
    ace12  
       2019-05-02 13:01:28 +08:00
    嘻嘻,没用过 js,感觉 clearInterval 的逻辑应该在 setInterval 的匿名函数外面
    kkkkkkkkkk
        4
    kkkkkkkkkk  
       2019-05-02 13:02:13 +08:00
    原因是 mouseover 被重复调用了,验证方法是你换一个事件,或者在"调用 mouseover"处增加一个断点。
    kkkkkkkkkk
        5
    kkkkkkkkkk  
       2019-05-02 13:02:49 +08:00
    @ace12 不用的,setInterval 返回一个 timeout ID,clearInterval 清除之,没问题
    kkkkkkkkkk
        6
    kkkkkkkkkk  
       2019-05-02 13:05:12 +08:00
    mouseover 本来应该只触发一次,但是我认为在你的这个 case 里因为 content 元素一直在动,所以重复触发了,建议换一个事件来触发这个逻辑。
    Oceanhime
        7
    Oceanhime  
       2019-05-02 13:05:20 +08:00
    @kkkkkkkkkk 应该不是事件被重复调用的问题, 代码里面 timer 被定义成了成员变量, 在 setInterval function 里面是没用的..?
    ochatokori
        8
    ochatokori  
       2019-05-02 13:29:37 +08:00 via Android   ❤️ 1
    @Oceanhime #7 timer 在最顶层声明了啊

    我来说吧
    这里楼主明显是调用了两次 mouseover
    但是 timer 变量两次都是同一个
    意思就是第一次 mouseover 中的 setInterval 返回的 timeoutId 被第二次覆盖了,所以清除定时器的时候只清除了第二个定时器
    Lax
        9
    Lax  
       2019-05-02 13:33:10 +08:00   ❤️ 1
    每次调用 mouseover 时都会生成新的定时器并赋值给 timer。旧的定时器失去了变量引用,不会被清除,但是仍然有效,会一直执行下去。
    Oceanhime
        10
    Oceanhime  
       2019-05-02 13:33:47 +08:00 via iPad
    @ochatokori 是的, 我没看到...
    manyfreebug
        11
    manyfreebug  
    OP
       2019-05-02 13:34:00 +08:00
    @kkkkkkkkkk mouserover 被重复调用,也就是说明启动了两个定时器。但是当 content.offsetLeft == 0 的时候,都会调用 clearInterval()方法来清除掉定时器啊。所以不是只会输出两个"A"吗 ? 但运行结果是:偶尔只输出两个"A", 但大部分时候会输出非常多的“ A ”
    manyfreebug
        12
    manyfreebug  
    OP
       2019-05-02 13:35:40 +08:00
    @Lax thanks
    crs0910
        13
    crs0910  
       2019-05-02 23:32:29 +08:00 via iPhone
    @Oceanhime 不加是全局变量,加了是作用域变量。你说的成员变量 js 并没有,要实现也是用 this 实现的。
    zzjas98
        15
    zzjas98  
       2019-05-03 00:59:32 +08:00
    问题在 timer 不该在 global scope,#9 正解。https://s3-us-west-1.amazonaws.com/zzjas/public/Image_KjHJM7ZKap.png 这样就完了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2642 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 10:54 · PVG 18:54 · LAX 02:54 · JFK 05:54
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.