Javascript导致浏览器挂起

Javascript causes browser to hang

本文关键字:挂起 浏览器 Javascript      更新时间:2023-09-26

即使控制台日志将while表达式指定为false,循环也会无限运行。

var tile_height;
$(document).ready(function(){
tile_height = $("#department > .front").height();
        });
        function tile_animate(e){
        console.log(($('> .front',e).css("height") > '0px') && ($('> .back',e).height() < tile_height));
        while(($('> .front',e).css("height") > '0px') && ($('> .back',e).height() <  tile_height)) 
            {
                $('> .front',e).animate({height: '-=1px'});
                $('> .back',e).animate({height: '+=1px'});
            }
        }

我已经尝试过使用if语句作为递归函数,但这也不起作用。使用while会导致浏览器停止响应。调用函数的html代码是

HTML代码

<div class="tiles" id="gallery" onmouseover="javascript:tile_animate(this)">
    <div class="front">
    </div>
    <div class="back">
    </div>
</div>

问题是您在悬停时使用循环。更好的方法是在样式中使用jQuery动画,并在必要时应用它。

然而,你描述这个问题的方式,看起来你将收缩div一次-之后没有什么可以恢复它。我注意到,div被命名为"部门",但JavaScript正在寻找"画廊"-所以我改变了…

所以,要像你现在的代码那样执行它,需要做一些调整:

删除while循环并在悬停时执行检查。

检查动画是否已经开始。

如果动画正在发生,忽略悬停。

如果动画还没有发生,设置一个标志来表示它已经发生了,并执行所需的动画-而不是逐像素减小div的大小(这是动画为您做的)。

完成后,div的高度将为0px(并且不能再次悬停)。

如果你想稍后恢复div,然后在动画之前存储它的原始尺寸,并在需要时恢复它们(不要忘记重置inLoop变量)…

var tile_height;
var inLoop = false;
$(document).ready(function() {
  tile_height = $("#gallery > .front").height();
});
function tile_animate(e) {
  if (!inLoop && ($('> .front', e).css("height") > '0px') && ($('> .back', e).height() < tile_height)) {
    inLoop = true;
    $('> .front', e).animate({
      height: '0px'
    });
    $('> .back', e).animate({
      height: tile_height
    });
  }
}

Javascript是单线程的。特别是,代码必须在另一个线程启动之前完成执行。另一个你真正感兴趣的线程是Jquery的动画循环,它默认在一个14毫秒的计时器线程上循环。

因此,你的while循环是无限运行的,因为动画代码永远不会运行以减少你正在测试的高度,并期望达到零。

既然你正在使用jQuery,为什么不直接嵌入代码并从JS中的事件处理程序触发函数:

var tile_height;
$(document).ready(function() {
  tile_height = $("#department > .front").height();
  $("#gallery").mouseover(function() {
    e = this;
    console.log(($('> .front', e).css("height") > '0px') && ($('> .back', e).height() < tile_height));
    while (($('> .front', e).css("height") > '0px') && ($('> .back', e).height() < tile_height)) {
      $('> .front', e).animate({
        height: '-=1px'
      });
      $('> .back', e).animate({
        height: '+=1px'
      });
    }
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<div class="tiles" id="gallery">
  <div class="front">front</div>
  <div class="back">back</div>
</div>