You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

随机筛选3个幻灯片并隐藏未选中项的代码问题排查

问题解决:轮播组件随机显示3个幻灯片并完全隐藏其余

问题描述

我有一个包含5个幻灯片的HTML和JavaScript轮播组件,需求是页面每次加载时随机选中3个幻灯片进行显示,完全隐藏未被选中的2个幻灯片。但当前代码运行后,5个幻灯片都会显示,仅随机3个有内容、2个为空,我需要让这2个空白幻灯片完全不显示,烦请帮忙排查代码问题。

问题根源

  1. 初始显示逻辑错误:原代码仅给选中的3个幻灯片设置display:block,但未对未选中的设置display:none,且这段代码在window.onload外执行,DOM可能未完全加载导致设置失效。
  2. 轮播逻辑未同步更新:轮播代码仍会遍历全部5个幻灯片和对应的指示器(dots),即使幻灯片被隐藏,轮播逻辑还是会切换到这些隐藏的幻灯片,导致空白显示。
  3. 筛选逻辑冗余:所有幻灯片本身都是非空内容,nonEmptySlogans会包含全部5个元素,这个筛选没有实际作用。

修复后的代码

HTML(无需修改)

<div class="container">
  <section id="testim" class="testim">
    <div class="testim-cover">
      <div class="wrap">

        <span id="right-arrow" class="arrow right fa fa-chevron-right"></span>
        <span id="left-arrow" class="arrow left fa fa-chevron-left "></span>
        <ul id="testim-dots" class="dots">
          <li class="dot active"></li>
          <!--
                    -->
          <li class="dot"></li>
          <!--
                    -->
          <li class="dot"></li>
          <!--
                    -->
          <li class="dot"></li>
          <!--
                    -->
          <li class="dot"></li>
        </ul>
        <div id="testim-content" class="cont">

          <div class="slogan">
            <p>"How does visual identity design help business/product value grow?"</p>
            <h2>MINE</h2>
          </div>

          <div class="slogan">
            <p>"How can we analyze ourselves, audience, competitors, and market and help business progress/grow?"</p>
            <h2>MINE</h2>
          </div>

          <div class="slogan">
            <p>"How can I differentiate my business from others?"</p>
            <h2>MINE</h2>
          </div>

          <div class="slogan">
            <p>"What is the best and latest business model and plan for me?"</p>
            <h2>MINE</h2>
          </div>

          <div class="slogan">
            <p>"How will innovative targeting be achieved at each stage of business?"</p>
            <h2>MINE</h2>
          </div>

        </div>

      </div>
    </div>
  </section>
</div>

JavaScript(修复后)

'use strict'
var testim = document.getElementById("testim"),
  testimDotsContainer = document.getElementById("testim-dots"),
  testimDots = Array.prototype.slice.call(testimDotsContainer.children),
  testimContentContainer = document.getElementById("testim-content"),
  testimContent = Array.prototype.slice.call(testimContentContainer.children),
  testimLeftArrow = document.getElementById("left-arrow"),
  testimRightArrow = document.getElementById("right-arrow"),
  testimSpeed = 4500,
  currentSlide = 0,
  currentActive = 0,
  testimTimer,
  touchStartPos,
  touchEndPos,
  touchPosDiff,
  ignoreTouch = 30;

window.onload = function() {
  // 第一步:随机选择3个幻灯片并隐藏其余
  const allSlogans = Array.from(document.querySelectorAll('.slogan'));
  // 先隐藏所有幻灯片
  allSlogans.forEach(slogan => slogan.style.display = 'none');
  
  // 随机选中3个不重复的幻灯片
  const selectedIndices = [];
  while (selectedIndices.length < 3) {
    const randomIndex = Math.floor(Math.random() * allSlogans.length);
    if (!selectedIndices.includes(randomIndex)) {
      selectedIndices.push(randomIndex);
      allSlogans[randomIndex].style.display = 'block';
    }
  }

  // 第二步:更新轮播相关的数组和指示器
  // 筛选出选中的幻灯片,更新testimContent
  testimContent = testimContent.filter((item, index) => selectedIndices.includes(index));
  // 筛选出对应的指示器并移除未选中的
  testimDots = testimDots.filter((dot, index) => {
    if (selectedIndices.includes(index)) {
      return true;
    } else {
      dot.remove();
      return false;
    }
  });

  // Testim Script
  function playSlide(slide) {
    for (var k = 0; k < testimDots.length; k++) {
      testimContent[k].classList.remove("active");
      testimContent[k].classList.remove("inactive");
      testimDots[k].classList.remove("active");
    }

    if (slide < 0) {
      slide = currentSlide = testimContent.length - 1;
    }

    if (slide > testimContent.length - 1) {
      slide = currentSlide = 0;
    }

    if (currentActive != currentSlide) {
      testimContent[currentActive].classList.add("inactive");
    }
    testimContent[slide].classList.add("active");
    testimDots[slide].classList.add("active");

    currentActive = currentSlide;

    clearTimeout(testimTimer);
    testimTimer = setTimeout(function() {
      playSlide(currentSlide += 1);
    }, testimSpeed)
  }

  testimLeftArrow.addEventListener("click", function() {
    playSlide(currentSlide -= 1);
  })

  testimRightArrow.addEventListener("click", function() {
    playSlide(currentSlide += 1);
  })

  for (var l = 0; l < testimDots.length; l++) {
    testimDots[l].addEventListener("click", function() {
      playSlide(currentSlide = testimDots.indexOf(this));
    })
  }

  playSlide(currentSlide);

  // 键盘快捷键
  document.addEventListener("keyup", function(e) {
    switch (e.keyCode) {
      case 37:
        testimLeftArrow.click();
        break;

      case 39:
        testimRightArrow.click();
        break;

      default:
        break;
    }
  })

  testim.addEventListener("touchstart", function(e) {
    touchStartPos = e.changedTouches[0].clientX;
  })

  testim.addEventListener("touchend", function(e) {
    touchEndPos = e.changedTouches[0].clientX;

    touchPosDiff = touchStartPos - touchEndPos;

    if (touchPosDiff > 0 + ignoreTouch) {
      testimLeftArrow.click();
    } else if (touchPosDiff < 0 - ignoreTouch) {
      testimRightArrow.click();
    } else {
      return;
    }

  })
}

修复说明

  1. 调整显示逻辑:先隐藏所有幻灯片,再随机选中3个设置为显示,确保未选中的完全隐藏。
  2. 同步轮播数据:更新testimContent数组为仅包含选中的幻灯片,同时移除未选中的指示器(dots),让轮播逻辑只处理有效幻灯片。
  3. 优化执行时机:将随机选择逻辑放到window.onload内部,确保DOM加载完成后再操作元素。

内容的提问来源于stack exchange,提问作者Fma88

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 12:20:03