【问题标题】:jQuery $.post causes browser stack overflowjQuery $.post 导致浏览器堆栈溢出
【发布时间】:2012-04-10 13:50:27
【问题描述】:

我有以下 jQuery 代码:

var id_atual
var temp_id
var tempo_flash = 50
var $slide_atual = $('#slider .atual')
var $slide_prox = $('#slider .ocultar')
setInterval(function(){
    id_atual = $slide_atual.attr('alt')
    $.post('get_banner.php', {atual: id_atual}, function(proximo){
        temp_id = proximo.split(';;')
        $slide_prox.attr('src', temp_id[0]).load(function(){
            $slide_atual.hide('fade', tempo_flash, function(){
                $slide_atual.attr('alt', temp_id[1]).attr('src', temp_id[0]).load(function(){
                    $slide_atual.show('fade', tempo_flash)
                })
            })
        })
    })
}, 4000)

以及以下 HTML 代码:

<div id="slider">
    <img src="imagens/slider/imagen-slider.jpg" alt="1" class="atual"/>
    <img src="" alt="" class="ocultar" />
</div>

.ocultar 类有一个

display: none;

vars tempo_flash 只是动画时间,get_banner.php 文件只用于从mysql 数据库中获取下一个banner。它经过测试并且工作正常。 我遇到的问题是,经过一点点(4 或 5 条横幅更改)后,浏览器停止响应(对于 Firefox Chrome 和 Opera),在 IE 上我收到警告 Stack overflow at line: 3 并且整个页面的 javascript 停止工作。

任何帮助表示赞赏!

【问题讨论】:

  • 您是否尝试过使用调试器单步执行您的代码?
  • 你应该花钱修好分号键 :-)
  • 尝试将您的$.post() 更改为$.ajax() 并包含timeout 参数。我想 AJAX 请求需要一些时间才能完成并堆积起来,因此会占用浏览器资源。
  • 我认为问题的一部分可能是您在函数外部声明了所有这些变量。没有理由这样做;它们应该在传递给setInterval() 的函数内部 声明。事实上,这些单独的功能很可能会互相影响。
  • 我尝试将 var 声明放入其中,但遇到了同样的错误...我现在正尝试更改为 $.ajax,但萤火虫说每个帖子的时间少于 200 毫秒。 ..

标签: javascript jquery browser stack-overflow .post


【解决方案1】:

在 setInterval()ed 函数的每次迭代中,您将 .load() 事件分配给图像占位符。将事件分配给对象不会删除现有的事件

所以在第二次迭代中,图像占位符将有两个 .load() 事件处理程序,然后是三个,依此类推;并且每次加载图像时,它都会触发附加到.load() 事件的所有事件处理程序。您可能需要重构您的代码,可能只分配一次.load() 事件处理程序(并使用分号)。

【讨论】:

  • 取消所有的 .load() 事件,它停止给出“堆栈溢出”错误,所以它解决了!!!!!!谢谢萨尔曼,有没有更好的方法在更改“src”后仅在图像完成加载时触发事件?
  • .load() 事件附加到元素,以便在图像完成加载时触发。在回调函数中,您可以检查$(this).attr("src") 以检查加载了哪个图像。
【解决方案2】:

你不应该使用 setInterval,你应该在函数内部使用 setTimeout,并在 $.post 的回调中执行它,类似于:

var id_atual
var temp_id
var tempo_flash = 50
var $slide_atual = $('#slider .atual')
var $slide_prox = $('#slider .ocultar')
function tictac(){
    setTimeout(function(){
        id_atual = $slide_atual.attr('alt')
        $.post('get_banner.php', {atual: id_atual}, function(proximo){
            temp_id = proximo.split(';;')
            $slide_prox.attr('src', temp_id[0]).load(function(){
                $slide_atual.hide('fade', tempo_flash, function(){
                    $slide_atual.attr('alt', temp_id[1]).attr('src', temp_id[0]).load(function(){
                        $slide_atual.show('fade', tempo_flash)
                    })
                })
            })
        })
        ticktac();
    }, 4000);
}

这样,只有在服务器响应完成时才开始计算 4 秒,不会出现溢出问题

【讨论】:

  • 我刚刚尝试过这个并得到了同样的错误......它在 tarcisiofotografia.com.br/site 上运行
  • 我尝试在 setTimeout 之外使用递归,例如 setTimeout(function(){ ... },4000); tictac() 什么都没有……
  • 如果你麻烦重写,为什么不包括分号呢? ;)
猜你喜欢
  • 2015-05-21
  • 2014-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-11
  • 2015-12-21
  • 2018-11-27
相关资源
最近更新 更多