【问题标题】:Smoothest way to move a div with JS/jQuery使用 JS/jQuery 移动 div 的最流畅方法
【发布时间】:2011-07-09 19:40:11
【问题描述】:

我需要将一个 div 从屏幕的右侧移动到左侧,但是同时使用经典的 JS 和 jQuery 会使它变得生涩:

我的 div:

<div class="lisp" id="lisp0" style="top:100px;">)</div>
<div class="lisp2" id="lisp1" style="top:300px;">)</div>

经典的javascript方法:

function move()
{
  pos = parseInt($("#lisp1").css("right"));
  $("#lisp1").css("right", pos+10+"px");
}
var interval = setInterval("move()",10);

jQuery 方法:

$("#lisp0").animate({"left": "-=2200px"}, 10000);

我创建了一个webpage 来向您展示它的生涩程度。第一步是使用 jQuery(最流畅的),第二步是使用经典 JS。有几个 div(和经典 JS),it starts to be really annoying. 我尝试修改jQuery.fx.interval,但并没有真正提高性能。

所以我的问题是:让这些 div 顺利移动的最佳方法是什么?

【问题讨论】:

  • 这对我来说看起来很流畅。你使用的是什么浏览器?没有什么可以让 IE7 更快/更流畅,而且 IE8 也会变得非常缓慢和笨重。
  • 我在 Ubuntu 10.10 下的 Chromium 和 Firefox 上尝试过。我没有在 Windows 上尝试过,但我认为它可能没有帮助。
  • 嗯,它在 Chrome 上并不完美,但对我来说似乎并没有那么糟糕。不幸的是,到今天为止,世界上的浏览器还没有成为理想的动画平台。很多人还在使用他们 1999 年的电脑……
  • 你可以做很多事情来优化你的代码,比如在经典方法中存储对象和位置值;当您在屏幕上为大量对象设置动画时,这会更好。
  • “存储对象”是什么意思?

标签: javascript jquery html jquery-animate move


【解决方案1】:

你让我举个例子来提高速度,我不是专家,但我会这样做:

  1. 不要将setInterval 与字符串函数一起使用,它们必须通过eval 才能运行,因此请改用它。事实上,我根本不会在主循环中使用 setInterval(参见第 3 点)。

    setInterval(doSomething, 100)
    
  2. 存储您将多次使用的对象(尤其是在不断循环的函数中)。即使这个例子也不理想:

    var lisp = $('#lisp1');
    function move()
    {
     var pos = parseInt( lisp.css("right"), 10 ); // always use a radix
     lisp.css("right", pos + 10 + "px");
    }
    
  3. 对于不断循环的函数,尽可能简短简洁,并消除额外的函数调用。从你的第二个链接,我压缩了这段代码:

    function move(){
          $(".lisp").each(function(){
    pos = parseInt($(this).css("right"));
        if (pos > width)
          $(this).remove();
        else
          $(this).css("right", pos+speed+"px")
      });
      $(".bonus").each(function(){
        pos = parseInt($(this).css("right"));
        if (pos > width)
          $(this).remove();
        else
          $(this).css("right", pos+speed+"px")
      });
      $(".special").each(function(){
        pos = parseInt($(this).css("right"));
        if (pos > width)
          $(this).remove();
        else
          $(this).css("right", pos+speed+"px")
      });
    }
    

    进入这个更简洁的版本:

    function move(){
      $(".lisp, .bonus, .special").each(function(){
        var pos = parseInt(this.style.right || 0, 10);
        if (pos > width) {
          $(this).remove();
        } else {
          this.style.right =  pos + speed + "px";
        }
      });
      if (!over) { setTimeout(move, 10); } // use this instead of the setInterval()
    }
    

    仍然不理想,因为您的代码不断添加越来越多的对象。它应该是有限的,因为有一次我在屏幕上有超过 200 个对象并且页面开始爬行。这也是为什么我会在最后一行使用 setTimeout 而不是您使用的 setInterval 的原因,因为在您希望脚本重新开始之前,该脚本可能没有循环遍历所有元素。

我确信其他人可以添加更多点来进一步优化我或您的代码:)

【讨论】:

  • 非常感谢!我会尽快尝试的!
猜你喜欢
  • 2011-07-01
  • 2017-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-25
  • 1970-01-01
  • 1970-01-01
  • 2011-09-13
相关资源
最近更新 更多