为什么这个JavaScript循环不起作用?

为什么这个JavaScript循环不起作用?,javascript,slideshow,Javascript,Slideshow,编辑:我有一个新的问题。Next()已更改为以下内容: var nextClicked = 0; function next() { nextClicked = 1; cycler(); } 我也尝试过: var nextClicked = 0; function next() { nextClicked++; cycler(); } 在这两种情况下,当下一个函数启动时,nextClicked变量值中的更改永远不会发

编辑:我有一个新的问题。Next()已更改为以下内容:

  var nextClicked = 0;
  function next()
  {
    nextClicked = 1; 
    cycler(); 
  } 
我也尝试过:

  var nextClicked = 0;
  function next()
  {
    nextClicked++; 
    cycler(); 
  } 
在这两种情况下,当下一个函数启动时,nextClicked变量值中的更改永远不会发生。我在Chrome Inspector中看到了这行代码,但变量值从未改变。我不知所措。我在搜索中没有发现任何与此相关的参考资料(尽管对过去的问题更熟悉的人可能会更幸运)。有人能解释这种奇怪的行为吗?谢谢大家!

编辑:按照下面的建议删除括号,解决了图像循环无法执行的问题,非常感谢

这是一个JavaScript图像幻灯片。每个图像显示5秒钟,然后显示下一个图像。当到达最终图像时,循环重新开始。当我按顺序写出这段代码时,一切都很顺利:


无需在超时内调用函数,只需给出引用即可


setTimeout(窗口[callFunction](),毫秒)
setTimeout(窗口[callFunction],毫秒)

我只是想把它作为一种不同的方法扔掉。您可以很容易地添加一些内容,以在
循环时中断
,或仅在用户单击特定元素后使其前进

const loadImage=url=>
新承诺((解决、拒绝)=>{
设img=document.createElement('img')
img.src=url
img.onload=event=>resolve(img)
img.onerror=err=>拒绝(err)
})
常量displayImage=({elem,images,index,ms})=>
新承诺(解决=>{
elem.src=images[index].src
setTimeout(解析,毫秒,{elem,图像,索引:(索引+1)%images.length,毫秒})
})
常量幻灯片=(元素、URL)=>
Promise.all(url.map(loadImage))
.then(images=>({elem,images,index:0,ms:1000}))
异步函数播放幻灯片(x){
while(true)
x=等待显示图像(x)
}
const logError=err=>console.error(err.message)
//演示
const elem=document.querySelector(“#slideshow img”)
常量imageUrls=[
'http://placehold.it/200?text=A',
'http://placehold.it/200?text=B',
'http://placehold.it/200?text=C',
'http://placehold.it/200?text=D',
'http://placehold.it/200?text=E'
]
幻灯片放映(元素、图像URL)
.然后(播放幻灯片,记录错误)

您正在做的事情似乎相当复杂。我建议您按照以下方式重写:

var runningTimeout = null;
var minImage = 1;
var maxImage = 5;
var currentImage = minImage;
var timerMiliseconds = 5000;

function cycler() {
    //In case this method is called from "outside" (prev/next) we clean the timeout.
    //This way there are no stray timeout that would cause unwanted behavior.
   if(runningTimeout != null) {
        clearTimeout(runningTimeout);
        runningTimeout = null;
  }
  //This part provides the cycling. If previous on first image sould display the last image,
  //divide the "if" in two ifs -> if currentImage < minImage then currentImage = maxImage.
  if(currentImage > maxImage || currentImage < minImage){
    currentImage = minImage;
  }
    console.log(currentImage++); //here display the image
  //Set the timeout again for the next iteration with the next image.
  runningTimeout = setTimeout(cycler, timerMiliseconds );
 }

 function prev() {
    //-2 because cycler did currentImage++ -> Displayed image = 4, currentImage = 5,
    //previous image = 3 => current (5) - 2 = previous (2)
    currentImage -= 2;
    cycler();
    //To stop cycling...
    if(runningTimeout != null) {
        clearTimeout(runningTimeout);
        runningTimeout = null;
    }
 }

 function next() {
    //cycler itself does currentImage++. Therefore there is no need to increment, just call 
    //it again for the currently set currentImage.
    cycler();
    //To stop cycling...
    if(runningTimeout != null) {
        clearTimeout(runningTimeout);
        runningTimeout = null;
    }
 }
var runningTimeout=null;
var最小值=1;
var最大值=5;
var currentImage=最小值;
var timerMiliseconds=5000;
函数循环器(){
//如果从“外部”(prev/next)调用此方法,我们将清除超时。
//这样就不会出现会导致不必要行为的错误超时。
if(runningTimeout!=null){
clearTimeout(运行超时);
runningTimeout=null;
}
//此部分提供循环。如果第一个图像上的上一个图像应显示最后一个图像,
//将“如果”分成两个“如果->如果当前图像<最小值,则当前图像=最大值”。
如果(当前图像>最大值| |当前图像<最小值){
currentImage=最小值;
}
console.log(currentImage++);//此处显示图像
//使用下一个图像再次设置下一次迭代的超时。
runningTimeout=setTimeout(循环器,timerMiliseconds);
}
函数prev(){
//-2因为Cycle没有显示currentImage++->Displayed image=4,currentImage=5,
//上一张图片=3=>当前(5)-2=上一张(2)
currentImage-=2;
cycler();
//停止骑自行车。。。
if(runningTimeout!=null){
clearTimeout(运行超时);
runningTimeout=null;
}
}
函数next(){
//cycler本身没有currentImage++。因此不需要增加,只需调用
//对于当前设置的currentImage,请再次执行此操作。
cycler();
//停止骑自行车。。。
if(runningTimeout!=null){
clearTimeout(运行超时);
runningTimeout=null;
}
}

至于图像,我建议您加载一次并隐藏它们,而不是每次都“动态”创建图像元素。这样,您只需设置它们的可见性,而不是重写内部html…

也可能重复,这与问题无关,但为每个图像创建单独的函数并不是实现这一点的最干净的方法。将图像放在一个数组中,只需一个函数即可将其从数组中拉出。您已单击+=1,但似乎从未重置它,因此第一次单击之后的任何单击都将被忽略。这是正确的行为,RobG。只需一次额外的点击就可以摆脱图像循环,因此该函数在再次点击后退出。谢谢JJJ,请查看我的上面的编辑。谢谢Viliam Aboši我会记住这一点。我现在(有点)在工作next(),只是自行车一直停下来。我原以为幻灯片放映会停滞不前。有什么想法吗?从来没有骑过自行车stops@TonyLuigiC至于最初的问题,我认为它不应该停止。你想什么时候停止?然而,如果你想停止它,你需要做的就是
clearTimeout(runningTimeout);runningTimeout=null我希望它在单击“上一步”或“下一步”按钮时停止。我想你刚刚发布了我需要的内容,非常感谢。@Viliam AbošI这里有一件奇怪的事情:我更改了next()函数,以便它调用cycler()并中断图像循环。函数next(){nextClicked=1;cycler();}我也尝试了函数next(){nextClicked++;cycler();}但是,在这两种情况下,变量值都保持为零。我在Chrome Inspector中看到过,这一行被读取,但被忽略,好像它不存在一样。你知道这是什么原因吗?
  <script type="text/javascript">
  <!--

  var clicked = 0;    
  var imageNumber = 1; 
  var mSeconds = 0; 
  var nextClicked = 0;
  var prevClicked = 0;   
  var callFunction = '';   

  function cycle()
  {      
    clicked += 1;  // repeatedly clicking slide show button disrupts image cycling, trap this error.
    if (clicked > 1) return; 
    cycler(); 
  }

  function cycler()
  {        
    for (i = 1; i < 10; i++)
    {  
      if (nextClicked == 1)
      {
        imageNumber++; 
        mSeconds = 0; 
        window['image' + imageNumber]();      
      }

      if (prevClicked == 1)
      {
        imageNumber--; 
        mSeconds = 0; 
        window['image' + imageNumber]();      
      }

    callFunction = 'image' + imageNumber;  
    setTimeout(window[callFunction](), mSeconds);  // call image# function, set time
    imageNumber += 1; 
    mSeconds += 5000; 
    if (imageNumber == 9) {imageNumber = 1}; 
    if (mSeconds == 45000) {mSeconds = 0}; 
    }
  }  

  var navImages = '<br><br><img style="float:left;" src="back.png" alt="Previous Image" width="160" height="80" onClick="prev()" /><img style="float:right;" src="next.png" alt="Next Image" width="160" height="80" onClick="next()" />';   
  function image1()
  { 
    document.getElementById("cycle").innerHTML = '<img src="floating_city.jpg" alt="Floating City" width="800" height="532" /><br><div>Floating City - Created in Voyager</div>' + navImages;        
    document.getElementById("cycle").scrollIntoView();
  }   
  function image2() {document.getElementById("cycle").innerHTML = '<img src="frozen_lake.jpg" alt="Frozen Lake" width="800" height="532" /><br><div>Frozen Lake with Alien Antenna - Created in Voyager</div>' + navImages};   
  function image3() {document.getElementById("cycle").innerHTML = '<img src="paradise_peak.jpg" alt="Paradies Peak" width="800" height="532" /><br><div>Paradise Peak - Created in Voyager</div>' + navImages};   
  function image4() {document.getElementById("cycle").innerHTML = '<img src="northern_moon.jpg" alt="Northern Moon" width="800" height="532" /><br><div>Northern Moon - Created in MojoWorld</div>' + navImages};     
  function image5() {document.getElementById("cycle").innerHTML = '<img src="woman_on_alien_beach.jpg" alt="Woman on Alien Beach" width="800" height="532" /><br><div>Woman on Alien Beach - Landscape Created in Voyager - Figure Created in Poser</div>' + navImages}; 
  function image6() {document.getElementById("cycle").innerHTML = '<img src="mount_vanilla.jpg" alt="mount_vanilla" width="800" height="532" /><div>Mount Vanilla - Created in Voyager</div>' + navImages};  
  function image7() {document.getElementById("cycle").innerHTML = '<img src="blue_orbs.jpg" alt="Blue Orbs" width="800" height="532" /><div>Blue Orbs - Created in Bryce</div>' + navImages}; 
  function image8() {document.getElementById("cycle").innerHTML = '<img src="ufo_city.jpg" alt="UFO City" width="800" height="532" /><div>UFO Invasion - Created in Bryce - Pyrotechnics Created in Particle Illusion</div>' + navImages};  
  function image9() {cycler()};  // Create infinite loop (without crashing browser). 

  function next() {nextClicked = 1}; 
  function prev() {prevClicked = 1}; 

  --> 
</script>  
var runningTimeout = null;
var minImage = 1;
var maxImage = 5;
var currentImage = minImage;
var timerMiliseconds = 5000;

function cycler() {
    //In case this method is called from "outside" (prev/next) we clean the timeout.
    //This way there are no stray timeout that would cause unwanted behavior.
   if(runningTimeout != null) {
        clearTimeout(runningTimeout);
        runningTimeout = null;
  }
  //This part provides the cycling. If previous on first image sould display the last image,
  //divide the "if" in two ifs -> if currentImage < minImage then currentImage = maxImage.
  if(currentImage > maxImage || currentImage < minImage){
    currentImage = minImage;
  }
    console.log(currentImage++); //here display the image
  //Set the timeout again for the next iteration with the next image.
  runningTimeout = setTimeout(cycler, timerMiliseconds );
 }

 function prev() {
    //-2 because cycler did currentImage++ -> Displayed image = 4, currentImage = 5,
    //previous image = 3 => current (5) - 2 = previous (2)
    currentImage -= 2;
    cycler();
    //To stop cycling...
    if(runningTimeout != null) {
        clearTimeout(runningTimeout);
        runningTimeout = null;
    }
 }

 function next() {
    //cycler itself does currentImage++. Therefore there is no need to increment, just call 
    //it again for the currently set currentImage.
    cycler();
    //To stop cycling...
    if(runningTimeout != null) {
        clearTimeout(runningTimeout);
        runningTimeout = null;
    }
 }