Самый плавный способ перемещения div с помощью JS / jQuery - PullRequest
7 голосов
/ 06 марта 2011

Мне нужно переместить div справа налево от экрана, но использование классического JS и jQuery делает его прерывистым:

Мои дивы:

<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);

Я сделал веб-страницу , чтобы показать вам, как это отрывисто. Первый ход с jQuery (самый гладкий), второй с классическим JS. С несколькими элементами div (и классическим JS) начинает раздражать. Я пытался изменить jQuery.fx.interval, но это не увеличило производительность.

Итак, мой вопрос: каков наилучший способ сделать эти div'ы плавными?

1 Ответ

5 голосов
/ 06 марта 2011

Вы попросили у меня пример для улучшения скорости, я не эксперт, но вот что я бы сделал:

  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, который вы используете, потому что сценарий может не циклически проходить по всем элементам, прежде чем вы захотите запустить его снова.

Уверен, есть еще моменты, которые кто-то еще мог бы добавить, чтобы оптимизировать мой или ваш код еще больше:)

...