Получение функций для выполнения в нужное время (в очереди или одновременно)

#jquery #execution-time #queuing

#jquery #время выполнения #постановка в очередь

Вопрос:

Я написал небольшой скрипт, который случайным образом перетасовывает серию divs — это работает так, как ожидалось (или надеялся).

Моя проблема заключается в реализации. Я хочу, чтобы divs исчезали, перетасовывались и снова появлялись. Я обнаружил, что функция moveBox () выполняется одновременно с любой анимацией. Я пробовал вызывать it как функцию обратного вызова для всех элементов (fadeOut, delay и fadeIn) в анимации, но всегда с тем же эффектом — перетасовка и перераспределение divs происходит во время анимации и, следовательно, видна.

У меня есть решение (var ts = timeOut …), которое приводит к перетасовке, пока divs скрыты, но я не уверен, что это лучшее решение.

Я хотел бы знать, как контролировать порядок выполнения функций и должны ли они выполняться одновременно или последовательно. Мой код :

 <style>
    .tester{
        float:left;
        width:100px;
        height:100px;
        margin:5px;
        }
    .tester p{text-align:center;
        margin-top:20px;
    }
    .one{background-color:red;}
    .two{background-color:yellow;}
    .three{background-color:teal;}
    .four{background-color:blue;}
    .five{background-color:green;}
    .six{background-color:silver;}
</style>

<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
    jQuery(document).ready(function(){
        var anibase=jQuery(".tester").length;
        jQuery(".tester").fadeOut(1000);
        function moveBox(){
            function shuffle(){
                for (i = 0; i <= (anibase - 2); i  ) {
                    mover = Math.floor(Math.random() * (anibase - i));
                    if (mover != 0) {
                        mover = mover   i;
                        jQuery(".tester:eq("   mover   ")").insertBefore(".tester:eq("   i   ")");
                    };
                };
            };
            jQuery(".tester").fadeOut(1500).delay(500).fadeIn(1500);
            var ts = setTimeout(shuffle,1500);
            var t=setTimeout(moveBox,5000);
        };
        moveBox();
    });

</script>
<body>
    <div class="tester one">
        <p>box 1</p>
    </div>
    <div class="tester two">
        <p>box 2</p>
    </div>
    <div class="tester three">
        <p>box 3</p>
    </div>
    <div class="tester four">
        <p>box 4</p>
    </div>
    <div class="tester five">
        <p>box 5</p>
    </div>
    <div class="tester six">
        <p>box 6</p>
    </div>
</body>
  

заранее спасибо

Ответ №1:

jQuery обладает способностью вкладывать функции, эффективно контролируя порядок выполнения.

Во-первых, хотя в Javascript допустимо вложение функций, в данном случае в этом нет необходимости, рассмотрим следующий код:

 <script type="text/javascript">

  jQuery(document).ready(function(){
    moveBox();  //call the function that will do the work and then setTimeout
  });



  function moveBox(){
    jQuery(".tester").fadeOut("slow",function(){
      shuffle();
      $(this).fadeIn("slow");
      return;
    });
    var t=setTimeout(moveBox,5000);
  }

  function shuffle(){
    var anibase=jQuery(".tester").length;
    for (i = 0; i <= (anibase - 2); i  ) {
      mover = Math.floor(Math.random() * (anibase - i));
      if (mover != 0) {
        mover = mover   i;
        jQuery(".tester:eq("   mover   ")").insertBefore(".tester:eq("   i   ")");
      }
    }
  }
</script>
  

Важная часть, на которую здесь следует обратить внимание, заключается в следующем:

 jQuery(".tester").fadeOut("slow",function(){
  shuffle();
  $(this).fadeIn("slow");
  return;
});
  

Это проинструктирует jQuery

  1. Исчезает элемент .tester
  2. По завершении затухания выполните shuffle()
  3. Затем верните элементы в

Вы можете увидеть дополнительные примеры этого в документации по fadeOut, некоторые из примеров показывают связанные события

Кроме того, разделение определений ваших функций значительно облегчает чтение.

Комментарии:

1. Я попробую это, спасибо — я часто сдержан в определении функций после их вызова — кажется, я получаю сообщения об ошибках, в которых говорится, что «xy не является функцией»! Но я согласен, что если я смогу сделать это правильно, это сделает код более читаемым.

2. Если бы вы вызывали moveBox () вне $(document). ready() перед определением функции moveBox() …. тогда вы получите «moveBox не является функцией». Но поскольку moveBox находится внутри $(document). готово это будет выполнено только после того, как все будет загружено и документ перейдет в состояние «готово».

3. Это очень полезно, поэтому у меня теперь появилось больше вопросов! Я не знал, что вы можете объявлять функции вне doc ready… Это работает, но я получаю предупреждение «неизвестный псевдоклассный эквалайзер» в консоли. Мне нужно, чтобы переменная anibase была доступна для других подпрограмм, поэтому я не уверен, куда мне ее поместить. Существуют ли другие средства, кроме использования функций обратного вызова, для цепочки выполнения функций?

4. что ж, когда дело доходит до области видимости, переменная anibase существует только внутри функции shuffle(). вне этой функции она не существует. поэтому, если вам это нужно в другой функции, вы можете создать это снова в рамках этой функции. Или, если количество элементов .tester не изменяется, жестко запрограммируйте это. И третьим вариантом было бы заменить любое местоположение, где требуется переменная anibase, вызовом функции getAnibase(), которая возвращает jQuery(«.tester»). длина;

5. спасибо — я занят, пытаясь понять главу Джона Ресига о закрытии и области видимости! (в разделе «Изучение jQuery 1.3»)