。每个都不会持续循环通过

时间:2019-07-08 21:07:57

标签: jquery

我的印象是 .each 会不断循环遍历一个序列,直到被明确告知要返回false停止为止。但是,下面的脚本正确地循环了我的每个“ ticker-item”元素,但是在最后一个元素之后不再重复吗?

  <script>
    var a = [];
    $(".ticker-item").each(function(index) {
      a[index] = $(this);
      setTimeout(function() {
        a[index].addClass('current').delay(8e3).queue(function(next) {
          a[index].removeClass('current');
          return;
          next();
        });
      }, index * 8e3);
    });
  </script>

如何让此脚本循环返回,并在第一个循环后将“当前”添加到第一项?

3 个答案:

答案 0 :(得分:1)

我认为您假设$.each做的比您预期的要多。

例如:

<ul>
  <li class="ticker-item">1</li>
  <li class="ticker-item">2</li>
  <li class="ticker-item">3</li>
  <li class="ticker-item">4</li>
</ul>
// Loop through each
$('.ticker-item').each((i) => {})

以上内容将遍历所有报价项一次。如果您添加/删除/更新/计时器/等。您将不得不再次调用$.each来运行代码。

一个简单的例子:

function doSomethingtoList() {
 $('.ticker-item').each(() => /*blah blah*/)
}
// Loop every 5 secs.
setInterval(doSomethingToList, 5000)

答案 1 :(得分:1)

演示中有详细评论。

/** cycleItems(selector, time)
@Params: selector [string]: CSS/jQuery selector syntax to target   
         elements (ex. "ol li")
         time [number|1000*]: ms* or s units 
Toggles .active class to a single tag of a given selector at a given time interval perpetually.
*//*
This async function wraps the .removeClass() method in a Promise
(line B) and is ran sequentially by using the await keyword.
//A - Convert collection into an array of tags.
//B - deActivate() removes .active after a given time duration has
      elapsed. It returns a Promise to ensure that the setTimeout()
      is ran at the designated time as expected rather than run 
      after other tasks in stack and then begin.
//C - for...of loop iterates through the items array...
//D - ...adds .active...
//E - ...waits the given time (second @Param) then removes .active
      and moves on to the next tag.
//F - When the array is complete, cycleItems() is then recursively 
      called. This cycle is perpetual and there's no means to stop
      it other than a refresh or closing the tab. That feature is
      left for the OP to figure out. :P
*/
async function cycleItems(selector, time = 1000) {
  const items = $(selector).toArray(); //A
  const deActivate = (item, time) => { //B
    return new Promise(resolve => setTimeout(() => resolve($(item).removeClass('active')), time));
  }
  for (let item of items) { //C
    $(item).addClass('active'); //D
    await deActivate(item, time); //E
  }
  return cycleItems(selector, time); //F
}

cycleItems('li', 500);
:root {
  font: 500 small-caps 6vw/1.2 Times;
}

ol {
  counter-reset: number;
}

ol li {
  font: inherit;
  width: max-content;
  list-style-type: none;
  position: relative;
  padding: 0 5px 0 0;
}

ol li::before {
  font-family: Consolas;
  counter-increment: number;
  content: counter(number)".";
  margin-right: 0.25em;
  padding: 0 0 0 10px;
}

ol li:nth-of-type(-n+9)::before {
  content: "0"counter(number)".";
}

.active {
  background-color: #930;
  color: #FC0;
}

.active::after {
  content: '\2b50';
}
<ol>
  <li>Item</li>
  <li>Item</li>
  <li>Item</li>
  <li>Item</li>
  <li>Item</li>
  <li>Item</li>
  <li>Item</li>
  <li>Item</li>
  <li>Item</li>
  <li>Item</li>
  <li>Item</li>
  <li>Item</li>
</ol>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

答案 2 :(得分:0)

您可以递归调用循环逻辑。

function processItems() {
  var a = [];

  $(".ticker-item").each(function(index) {
    a[index] = $(this);
    setTimeout(function() {
      a[index].addClass('current').delay(8e3).queue(function(next) {
        a[index].removeClass('current');
        return;
        next();
      });

      if (a[index].is(':last-child')) {
        processItems(); // Run it again!
      }
    }, index * 8e3);
  });
}