Как сделать выполнение очереди функций в jS - PullRequest
1 голос
/ 09 апреля 2020

Я использую jQuery, чтобы сгладить скрытие и показ коробок. Например, если вы щелкнете, чтобы скрыть один ящик, он скроет все ящики, но затем появятся только те, которые не должны быть скрыты.

С показом было немного сложнее. Ящик, который должен был показать, показывался до того, как остальные закончили исчезать. Поэтому я добавил функцию setTimeout с ограничением по времени 400 мс (по умолчанию время появления / исчезновения в JQuery).

Теперь код работает нормально, за исключением одной мелочи. Если вы быстро нажмете все кнопки, ящики будут в очереди, чтобы исчезнуть. Так и должно быть. Однако, если вы повторите процесс (быстро нажмите все кнопки назад, чтобы все кнопки снова появились), он будет сбой.

Я повторил процесс на видео здесь: https://ctrlv.tv/video/2020/04/09/13/Ij9u.webm. - Вы можете видеть, что исчезающее выглядит гладко, но вновь появляющееся выглядит ужасно.

Я думаю, что это может происходить из-за функции setTimeout.

Есть ли способ go обойти это?

function showhide(num) {
  if ($("#box" + num).css('display') == 'none') {
    $(".box").fadeOut();
    
    setTimeout(function() {
      $("#box" + num).removeClass("hidden");
      $(".box:not(.hidden)").fadeIn();
    }, 400);
  } else {
    $(".box").fadeOut();
    $("#box" + num).addClass("hidden");
    $(".box:not(.hidden)").fadeIn();
  }
}
html {
  width: 340px;
  border-style: solid;
}

.box {
  width: 100px;
  height: 100px;
  float: left;
}

#box1 { background-color: red; }
#box2 { background-color: blue; }
#box3 { background-color: green; }
#box4 { background-color: yellow; }
#box5 { background-color: orange; }
#box6 { background-color: purple; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<b>Hide/Show</b><br>

<button onclick="showhide(1)">Box 1</button>
<button onclick="showhide(2)">Box 2</button>
<button onclick="showhide(3)">Box 3</button>
<button onclick="showhide(4)">Box 4</button>
<button onclick="showhide(5)">Box 5</button>
<button onclick="showhide(6)">Box 6</button><br><br>

<div id="box1" class="box"></div>
<div id="box2" class="box"></div>
<div id="box3" class="box"></div>
<div id="box4" class="box"></div>
<div id="box5" class="box"></div>
<div id="box6" class="box"></div>

jsFiddle

1 Ответ

1 голос
/ 09 апреля 2020

Проблема заключается в том, что вы полагаетесь на класс .hidden, которого нет в элементах, чтобы фейдер работал. Как только вы удалите этот класс, элемент появится снова.

Вы можете сделать логику c более эффективной и более простой, окружив элементы .box контейнером, который вы можете добавлять / выводить. В обратном вызове этого затухания вы можете затем скрыть / показать соответствующее поле, прежде чем снова отобразить видимые. Попробуйте это:

let $container = $('#box-container');

$('button').on('click', function() {
  var $target = $($(this).data('target'));
  
  $container.fadeOut(() => {
    $target.toggleClass("hidden");
    $container.fadeIn();
  });
});
html {
  width: 340px;
  border-style: solid;
}

.box {
  width: 100px;
  height: 100px;
  float: left;
}

.hidden { display: none; }

#box1 { background-color: red; }
#box2 { background-color: blue; }
#box3 { background-color: green; }
#box4 { background-color: yellow; }
#box5 { background-color: orange; }
#box6 { background-color: purple; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<b>Hide/Show</b><br>

<button data-target="#box1">Box 1</button>
<button data-target="#box2">Box 2</button>
<button data-target="#box3">Box 3</button>
<button data-target="#box4">Box 4</button>
<button data-target="#box5">Box 5</button>
<button data-target="#box6">Box 6</button><br><br>

<div id="box-container">
  <div id="box1" class="box"></div>
  <div id="box2" class="box"></div>
  <div id="box3" class="box"></div>
  <div id="box4" class="box"></div>
  <div id="box5" class="box"></div>
  <div id="box6" class="box"></div>
</div>

Также обратите внимание на использование ненавязчивых обработчиков событий. Встроенные атрибуты onX больше не являются хорошей практикой, и их следует по возможности избегать.

...