Почему эта анимация прерывистая и иногда имеет длительную задержку перед выполнением? - PullRequest
0 голосов
/ 07 января 2012

Эта анимация jquery очень изменчива в Firefox, и как в Firefox, так и в Chrome она часто имеет заметную задержку (~ 1 секунду), прежде чем она фактически начинает анимацию (если я добавлю код для записи на консоль при вызове обработчика onclick, это будет отображаться сразу, но вызов анимации будет иметь задержку).Эта задержка не каждый раз, но если вы нажмете, может быть, 5-6 раз, вы увидите ее хотя бы один раз.

<!doctype html>
<html>
    <head>
    <title>Test Lag</title>

    <script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>

    <style>
        .base
        {
            position: absolute;
            top: 507px;
            left: 0px;
            width: 1000px;
            height: 40px;
            z-index: 0;
        }

        .one
        {
            position: absolute;
            top: 2px;
            left: 2px;
            width: 994px;
            height: 34px;
            background-color: #ffffff;
            border: solid 1px #505050;
            z-index: 3;
            opacity: 0.5;
            filter: alpha(opacity=50);
        }

        .oneA
        {
            position: absolute;
            top: 0px;
            left: 0px;
            width: 966px;
            height: 6px;
            margin: 10px;
            background-color: #999999;
            border: solid #cccccc 4px;

        }

        .two
        {
            position: absolute;
            top: 1px;
            left: 1px;
            width: 996px;
            height: 36px;
            background-color: #e8e8e8;
            border: solid 1px #505050;
            z-index: 2;
            opacity: 0.25;
            filter: alpha(opacity=25);
        }

        .three
        {
            position: absolute;
            top: 0px;
            left: 0px;
            width: 998px;
            height: 38px;
            background-color: #e8e8e8;
            border: solid 1px #505050;
            z-index: 1;
            opacity: 0.12;
            filter: alpha(opacity=12);
        }

        .four
        {
            position: absolute;
            top: 17px;
            left: 17px;
            width: 966px;
            height: 6px;
            background-color: #e8e8e8;
            z-index: 0;
            opacity: 0.5;
            filter: alpha(opacity=50);
        }

        .five
        {
            position: absolute;
            top: 17px;
            left: 17px;
            width: 966px;
            height: 366px;
            z-index: 4;
            overflow: hidden;
        }
    </style>
    </head>
    <body>

    <div id ="base" class="base">
        <div id="one" class="one">
        <div id="oneA" class="oneA"></div>
        </div>
        <div id="two" class="two"></div>
        <div id="three" class="three"></div>
        <div id="four" class="four"></div>
        <div id="five" class="five">There's some text in here.</div>
    </div>

    <script>
       var isOn = false;

       var jq_base = $('#base');
       var jq_one = $('#one');
       var jq_oneA = $('#oneA');
       var jq_two = $('#two');
       var jq_three = $('#three');
       var jq_four = $('#four');

       var baseTop = 96;
       var baseStartTop =507;

       var baseHeight = 400;
       var oneHeight = 394;
       var oneAHeight = 366;
       var twoHeight = 396;
       var threeHeight = 398;
       var fourHeight = 366;

       var baseStartH = 40;
       var oneStartH = 34;
       var oneAStartH = 6;
       var twoStartH = 36;
       var threeStartH = 38;
       var fourStartH = 6

       document.onclick = function()
       {
           //It's opened
           if ( isOn )
           {
               jq_one.animate( { height: oneStartH }, { duration: 300, queue: false } );
               jq_oneA.animate( { height: oneAStartH }, { duration: 300, queue: false } );
               jq_two.animate( { height: twoStartH }, { duration: 300, queue: false } );
               jq_three.animate( { height: threeStartH }, { duration: 300, queue: false } );
               jq_four.animate( { height: fourStartH }, { duration: 300, queue: false } );
               jq_base.animate(
                   { height: baseStartH },
                   {
                       duration: 300,
                       queue: false,
                       step: function (now)
                       {
                           if ( now <= ( baseStartH + 10 ) ) jq_base.animate( { top: baseStartTop }, 800 );
                       }
                   }
               );

               isOn = false;
           }

           //It's closed
           else
           {
               jq_base.animate(
                   { top: baseTop },
                   {
                       duration: 800,
                       step: function (now)
                       {
                           if ( now <= 100 )
                           {
                               jq_base.animate( { height: baseHeight }, { duration: 300, queue: false } );
                               jq_one.animate( { height: oneHeight }, { duration: 300, queue: false } );
                               jq_oneA.animate( { height: oneAHeight }, { duration: 300, queue: false } );
                               jq_two.animate( { height: twoHeight }, { duration: 300, queue: false } );
                               jq_three.animate( { height: threeHeight }, { duration: 300, queue: false } );
                               jq_four.animate( { height: fourHeight }, { duration: 300, queue: false } );
                           }
                       }
                   }
               );
               isOn = true;
           }
       }
    </script>
    </body>
</html>

DEMO: http://jsfiddle.net/fnswz/

1 Ответ

2 голосов
/ 07 января 2012

Я думаю, что проблема в следующей части if (isOn) ветви:

  jq_base.animate(
      { height: baseStartH },
      {
          duration: 300,
          queue: false,
          step: function (now)
          {
              if ( now <= ( baseStartH + 10 ) )
                 jq_base.animate( { top: baseStartTop }, 800 );
          }
      }
  );

В частности, в рамках функции step этого конкретного вызова animate() вы запускаете другую анимацию с довольно большой продолжительностью (800 мс), и потому что она находится в step, даже если вы запускаете тест if несколько анимаций с такой длительностью.

Это означает, что, хотя процесс достигает точки, в которой он выглядит завершенным, потому что все переместилось в свою конечную позицию, за кулисами эти дополнительные анимации не закончились и поэтому не реагируют должным образом. на последующие клики. Если вы переместите эту 800-миллиметровую анимацию из функции step и просто вставите ее потом, то, похоже, все будет работать более плавно. (По крайней мере, в Chrome это выглядит намного лучше: как я уже говорил в моем комментарии выше, у меня нет FF на этом компьютере, поэтому я не могу это проверить.)

Вот демонстрация с изменениями, о которых я говорю: http://jsfiddle.net/fnswz/1/

Возможно, вы захотите установить флаг animationRunning при запуске анимации, а затем сбросить ее с помощью обратного вызова animate() complete, чтобы вы могли проверить флаг и игнорировать щелчки, пока текущая анимация не закончится, но только изменение выше сделало для меня большое улучшение.

(Кстати, почему вы используете document.onclick = ..., когда используете jQuery?)

...