首页 > 解决方案 > 循环浏览图像列表并随机显示一个并短暂闪烁

问题描述

我有以下html结构:

<ul class="posts">
    <li><img src="https://64.media.tumblr.com/1ff0b6435eaf4f2179e06cfbd9fca583/8fb2fa7b9e4b2d56-1f/s1280x1920/e1a986dea1f99a0cd9dcc7e672bb4a76254df4c4.jpg" class="hidden"></li>
    <li><img src="https://64.media.tumblr.com/70ec82e83c3c5835b10aec4927e253b8/8fb2fa7b9e4b2d56-d0/s540x810/c51483723f355f77a3ae6a17fe19da6525662b46.jpg" class="hidden"></li>
    <li><img src="https://64.media.tumblr.com/7d2f63f029ba23c1e4a6fe28fd6f52d7/8fb2fa7b9e4b2d56-80/s540x810/e6465ab8578c263f62075a2740b763822cbec270.jpg" class="hidden"></li>
    ...
</ul>

使用 css 设置项目:

.posts img {
    width: 100%;
    position: absolute;
}

.hidden {
    display: none;
}

.block {
    display: block;
}

这是我的 JS/jQuery:

const blockClass = 'block';
const hiddenClass = 'hidden';

function setRandomImage() {
    const randomIndex = (parseInt(Math.random() * $('.posts li').length));
    $('.posts img').removeClass(blockClass).addClass(hiddenClass); // remove block class and add hidden class from all elems. 
    sleep(2000);
    $(`.posts li:eq(${randomIndex}) img`).addClass(blockClass); // add block class to random item. 
    sleep(4000);
    $(`.posts li:eq(${randomIndex}) img`).removeClass(blockClass).addClass(hiddenClass); // remove block class and add hidden class to random item
    sleep(3000); // testing sleep function for 3s
}

setInterval(function () {
    setRandomImage();
}, 2000);

function sleep(milliseconds) {
    const date = Date.now();
    let currentDate = null;
    do {
        currentDate = Date.now();
    } while (currentDate - date < milliseconds);
}

这个概念是默认隐藏所有图像。从图像数组中选择一个随机索引,将display block类添加到其中,然后暂停一段时间(我希望图像非常短暂地闪现)然后它应该再次隐藏。

应该使用 sleep 功能来实现暂停。如果我只是添加一些控制台日志和不同的睡眠间隔,这似乎有效,直到间隔之后才会出现日志。

此外,如果我调试 js,我实际上可以看到图像属性设置正确。但是一旦它在浏览器中运行,这些项目就永远不可见。我不确定这是性能问题还是 jQuery 的一些怪癖。我只希望它们像频闪效果​​一样闪烁,但我尝试使用睡眠功能设置更长的持续时间,看看是否有任何效果。

编辑

如果这与性能有关,我想知道一种更好的实现方式,但据我所知,它应该是相当低的水平。

JSFIDDLE

标签: javascriptjquerytimersetinterval

解决方案


您的sleep功能是浏览器杀手!

它通过将其保持在 while 循环中几秒钟(这是long 的方式),重复地阻止所有 JS 执行。因此,如果您在网站上有按钮,则单击事件将不会响应。事实上,什么都不会。简而言之,这是一个可怕的想法。

要达到您想要的效果,只需有一个间隔来触发 CSS @keyframes动画以获得短暂的闪现效果。

这就是你所需要的:

function setRandomImage() {
  
  const randomIndex = parseInt(Math.random() * $(".posts li").length);
  
  // remove block class from all elems.
  $(".posts img").removeClass("block");
  
  // add block class to random item.
  $(`.posts li:eq(${randomIndex}) img`).addClass("block");

}

// The interval of 9 seconds
setInterval(function () {
  setRandomImage();
}, 9000);
setRandomImage();
.posts img {
  width: 100%;
  position: absolute;
  display: none;  /* The default hide is here */
}

.block {
  display: block !important;
  opacity: 0;
  animation: flashImg 2s;  /* That is the "flash" duration */
}

@keyframes flashImg {  /* And that is the flash animation */
  0% {opacity: 0;}
  10% {opacity: 1;}  /* play with the percentages to smooten the apparition */
  90% {opacity: 1;}
  100% {opacity: 0;}
}

li{
  list-style: none;  /* Removes li bullets */
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="posts">
    <li><img src="https://64.media.tumblr.com/1ff0b6435eaf4f2179e06cfbd9fca583/8fb2fa7b9e4b2d56-1f/s1280x1920/e1a986dea1f99a0cd9dcc7e672bb4a76254df4c4.jpg"></li>
    <li><img src="https://64.media.tumblr.com/70ec82e83c3c5835b10aec4927e253b8/8fb2fa7b9e4b2d56-d0/s540x810/c51483723f355f77a3ae6a17fe19da6525662b46.jpg"></li>
    <li><img src="https://64.media.tumblr.com/7d2f63f029ba23c1e4a6fe28fd6f52d7/8fb2fa7b9e4b2d56-80/s540x810/e6465ab8578c263f62075a2740b763822cbec270.jpg"></li>
</ul>


推荐阅读