【问题标题】:JavaScript setTimeout will not die.JavaScript setTimeout 不会死。
【发布时间】:2011-12-11 21:43:20
【问题描述】:

我制作了一个图片库,并且使用了 AJAX。下面是相关的代码。

    if (isset($_POST['stopss'])){
    echo'<script type="text/javascript">
    clearTimeout(setss);
    </script>';
    }

    if (isset($_POST['startss'])){
    ?>
    <script type="text/javascript">
    var setss = window.setTimeout('delayer(\''+src+'\',\''+dir+'\',\''+title+'\',\''+width+'\',\''+height+'\',\''+img+'\')',5000);
    </script>
    <?
    }

delayer 函数为新的模态框窗口(新的 AJAX 请求)传递参数。 我看到的问题。当用户单击幻灯片按钮时,超时开始。 即使他们按下停止幻灯片按钮(这会重新加载 AJAX 页面),计时器仍在运行(在后台)并且在 clearTimeout(setss) 中,sets 不再可用(因为新的 AJAX 页面请求)所以 clearTimeout清除失败。

有什么办法可以终止在后台运行的超时?即使 modalbox 窗口关闭,5 秒后它也会打开并愉快地继续播放幻灯片。

顺便说一句,这是模态框调用。 Modalbox.show('../b-gal-scripts/ajaxgal.php', {title: title, overlayOpacity: .1, width: width, height: height, method: 'post', params: {src: next,目录:目录,img:img,ssimg:下一个}});返回错误;

【问题讨论】:

  • 不是答案,但每次有人将字符串传递给setTimeout,上帝就会杀死一只小猫。 var setss = window.setTimeout(function() { delayer(src, dir, title, width, height, img) }, 5000);.

标签: javascript settimeout


【解决方案1】:

问题

当您重新加载页面时,旧的 JavaScript 代码(用于上一个请求)停止运行并执行新的。

问题是您首先调用clearTimeout(setss),然后定义setss 的真正含义。

几个额外的问题

一些提示:

  1. 不要混合引用样式,这样会造成混乱。
  2. 如果您想要引号内的引号,只需使用存在不同引号的事实

    var setss = window.setTimeout("delayer('"+src+'","'+dir+'","'+title+'","'+width+'","'+height+'","'+img+'")',5000);
    
  3. ...最好在编写 JavaScript 时习惯 基于事件的编程闭包,就像这样:

    var sets = window.setTimeout(function(){
        delayer(src, dir, title, width, height, img);
    }, 5000);
    

代码的最终版本

您的代码应如下所示:

if (isset($_POST['startss']) && !isset($_POST['stopss'])){
    ?>
    <script type="text/javascript">
        var setss = window.setTimeout(function(){
            delayer(src, dir, title, width, height, img);
        }, 5000);
    </script>
    <?
}

它利用了这样一个事实,即您不需要先输出一个脚本,该脚本只在不需要时立即停止执行。只需设置 PHP 条件来检查你是否希望它被执行,输出它。

其次,JS 已经从使用字符串(这完全是混乱的)更改为使用匿名函数。仔细研究一下。

有帮助吗?

【讨论】:

  • clearTimeout(setss) 仅在单击停止幻灯片按钮时调用,否则将被忽略。
    同样,只有在单击开始幻灯片按钮时才会调用 setTimeout。
    主页面不会改变,但模态框覆盖会随着每次按钮单击而改变。
    @Tadeck,会接受你的建议,我是一个 jS 菜鸟。
  • @LorenWolsiffer:是的,但它在setTimeout 被调用之前被调用。你看,这里的问题是你假设来自上一个请求的代码仍在执行,而它不是。当页面重新加载时,上一个请求中的 JavaScript 停止执行。
  • @LorenWolsiffer:你是说页面没有重新加载吗?我可能误解了你在说什么。我相信代码是一个比我以前想象的更大的问题。在使用 JavaScript 并将事件处理程序附加到“开始”和“停止”按钮时,您应该真正坚持基于事件的编程。因为您是从 JavaScript 开始您的旅程,所以我建议您使用 jQuery
  • 您可以在此处查看它的使用情况 floridayachtscharter.com/exterior-pictures/ 我确定问题出在新页面请求中,其中 sets 不可用。非常感谢您的帮助。
  • 我认为发生了什么,AJAX 输出脚本在主浏览器窗口中设置了超时,然后当再次调用 AJAX 输出脚本时,sets 不再可用,是否有类似 parent.window 的东西。 clearTimeout(setss);?
【解决方案2】:

我在理解您的问题时遇到了一点困难,但我希望这会有所帮助。

  1. 当重新加载页面时,页面的前一个实例以及与之关联的任何状态都将不复存在。结果,超时已停止。本质上,如果全局 setSS 不存在,那么它所引用的超时也不存在,因此,该超时不能负责启动幻灯片。

  2. 当从 PHP 之类的东西提供活动页面时,服务器的工作(WRT 创建页面的任何内容)就完成了。随后不能将更多内容写入页面。您的 clearTimeout 基本上没有用,因为它只能清除在页面加载期间设置的超时。它不会将新的脚本元素写入现有页面。

  3. 变量不会跨页面共享,因此如果您在一个页面中设置超时,而在另一个页面中清除它,这将不起作用。

因此,为了清除超时,您需要在与setTimeout 相同的页面(和该页面的实例)中调用clearTimeout,并且该调用必须在setTimeout 之后执行。

如果以上都不适用于您的情况,那么$_POST['startss']$_POST['stopss'] 是否可以在同一个请求中设置?如果是这样,新页面将在尝试清除它后创建一个新的超时,并因此显示幻灯片。

(顺便说一句,使用闭包创建一个传递给 setTimeout 的函数将比编译调用函数的字符串更具可读性)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-01
    • 1970-01-01
    • 2013-05-05
    • 2017-12-11
    • 2018-06-21
    相关资源
    最近更新 更多