我已经创建了一个自动幻灯片-点击"菜单项"后开始播放.我正在寻找一种方法来"关闭",当点击不同的"菜单项".整个问题可以抽象为一个简单的例子:

构建"stop"<li>的功能(可能使用stopInterval).我想不出一个解决方案,有人有什么 idea 吗?

const li1 = document.getElementById("li1")

li1.addEventListener("click", slideShowAbstract)

function slideShowAbstract(e) {

    const y = setInterval(()=> console.log("playing"), 2000)

    }
ul {
    display: flex;
    justify-content: center;
    list-style-type: none;
  }
  
li {
    margin: 1rem;
}

li:hover {
    cursor: pointer;
}
            <ul>
                <li id="li1">play</li>
                <li id="li2">stop</li>
            </ul>

推荐答案

更好的方法?

要避免全局变量会受到副作用的影响,请使用对象,您可以向其中添加有用的方法.

const 
  btPlay = document.querySelector('#bt-play')
, player = (()=> // IIFE  for object { play(), stop() } method
  {
  let // inside Object values ( closure )
    refIntv   = 0
  , counter   = 0
  , onProcess = false // security to avoid multiple setInterval processes
    ;
  function playerAction()  // inside private function
    {
    console.clear()
    console.log( 'playing', ++counter)
    }
  return {
    play()
      {
      if (onProcess) return  // security to avoid doing setInterval() twice
      
      onProcess = true
      counter   = 0
      console.clear()
      console.log('start playing')
      refIntv = setInterval( playerAction , 2000)
      }
  , stop()
      {
      if (!onProcess) return  // security to avoid doing clearInterval() twice
 
      clearInterval( refIntv )
      onProcess = false
      
      console.clear()
      console.log('stop playing')
      }
    }
  })();


btPlay.onclick =_=>
  {
  if (btPlay.classList.toggle('stopped'))  player.play()
  else                                     player.stop()
  }
button { 
 margin : 1em 3em;
 width  : 5em; 
 }
#bt-play::after { 
 content : 'play';
 }
#bt-play.stopped::after { 
 content : 'stop';
 }
<h5> case 1: same button for start and stop </h5>

<button id="bt-play"></button>
<!-- control by interface : same button for start and stop -->
<hr>

<h5> case 2: 2 buttons   </h5>

<button onclick="player.play()">play</button>
<button onclick="player.stop()">stop</button>

interface control:
if you have 2 buttons (start + stop), the user can click 2 times on the start button and you you end up with 2 overlapping interval processes (or more) without the possibility of finding the reference of the previous setInterval since this variable has been replaced to reference the process of the following interval

如果没有,您还可以添加一个测试,验证之前没有运行间隔进程.

Javascript相关问答推荐

node TS:JWT令牌签名以验证客户端和后台问题之间的身份验证

为什么我的includes声明需要整个字符串?

如何用显示网格平滑地将元素从一个地方移动到另一个地方?

如何在Connect 4游戏中 for each 玩家使用位板寻找7形状?

使用javascript将Plotly Expandable Sparkline转换为HighCharter Plot在bslib卡中

如何使用JavaScript将文本插入空div

有没有可能使滑动img动画以更快的速度连续?

为什么!逗号和空格不会作为输出返回,如果它在参数上?

更改JSON中使用AJAX返回的图像的路径

如何添加绘图条形图图例单击角形事件

简单的PayPal按钮集成导致404错误

如何将zoom 变换应用到我的d3力有向图?

如何在和IF语句中使用||和&;&;?

构建器模式与参数对象输入

为什么我的Navbar.css没有显示在本地主机页面上?

为什么这个最小Angular 的Licial.dev设置不起作用?

限制数组中每个元素的长度,

JSON Web令牌(JWT)错误:RSA密钥对的签名无效

如何在Java脚本中添加一个可以在另一个面板中垂直调整大小的面板?

在openstreemap/leaflet中,当鼠标在 map 上移动时,如何在小工具提示中实时显示坐标