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

Why is this JavaScript Loop not Working?

编辑:我遇到了一个新问题。 Next() 更改为以下内容:

  var nextClicked = 0;
  function next()
  {
    nextClicked = 1; 
    cycler(); 
  } 

我也试过:

  var nextClicked = 0;
  function next()
  {
    nextClicked++; 
    cycler(); 
  } 

在这两种情况下,当 Next 函数触发时,nextClicked 变量值永远不会发生变化。我已经在 Chrome Inspector 中看到了正在读取的行,但是变量值永远不会改变。我很茫然。而且我在搜索中没有找到任何对此的参考(尽管对过去的问题更熟悉的人可能更幸运)。谁能解释这种奇怪的行为?谢谢!

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

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

  <script type="text/javascript>
  var clicked = 0;  // repeatedly clicking slide show button disrupts image cycling, trap this error.  
  function cycle()
  {      
    clicked += 1; 
    if (clicked > 1) return; 
    cycler(); 
  } 

  function cycler()
  {        
    setTimeout(image1, 0000);  
    setTimeout(image2, 5000); 
    setTimeout(image3, 10000);
    setTimeout(image4, 15000);  
    setTimeout(image5, 20000); 
    setTimeout(image6, 25000);
    setTimeout(image7, 30000);     
    setTimeout(image8, 35000); 
    setTimeout(image9, 40000);
  }

  var navImages = '<br><br><img style="float:left;" src="back.png" alt="Previous Image" width="160" height="80" /><img style="float:right;" src="next.png" alt="Next Image" width="160" height="80" />';   
  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). 
  </script> 

然后,我尝试为“后退”和“下一步”按钮添加代码。这基本上要求在 每个 setTimeout 行之后插入代码,以便 image# 函数可以移动到下一个(或上一个)image# 函数、超时重置和循环器( ) 函数退出。所有这些代码似乎都是多余的,所以我将代码放在一个循环中。

  <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>  

还有……现在不行了。第一张图片出现,仅此而已。返回不起作用,下一步不起作用。当我设置断点并在 Chrome 中逐行执行时,图像的文本显示出来,好像一切正​​常。但在运行时,它只是卡在第一张图片上。

我是 JavaScript 的新手,非常感谢您的建议。

超时内无需调用函数,仅供参考

setTimeout(window[callFunction](), mSeconds); 应该是 setTimeout(window[callFunction], mSeconds);

只是想把它作为对整个事情的不同方法。您可以很容易地添加一些东西来中断 while 循环或仅在用户单击特定元素后才前进

const loadImage = url =>
  new Promise((resolve, reject) => {
    let img = document.createElement('img')
    img.src = url
    img.onload = event => resolve(img)
    img.onerror = err => reject(err)
  })
  
const displayImage = ({elem, images, index, ms}) =>
  new Promise(resolve => {
    elem.src = images[index].src
    setTimeout(resolve, ms, {elem, images, index: (index + 1) % images.length, ms})
  })
    
const slideshow = (elem, urls) =>
  Promise.all(urls.map(loadImage))
    .then(images => ({ elem, images, index: 0, ms: 1000 }))

async function playSlideshow (x) {
  while (true)
    x = await displayImage(x)
}

const logError = err => console.error(err.message)

// demo
const elem = document.querySelector('#slideshow img')

const 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'
]

slideshow(elem, imageUrls)
  .then(playSlideshow, logError)
  
<div id="slideshow">
  <img>
</div>

你做的事情似乎很复杂。我建议您按以下方式重写它:

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;
    }
 }

至于图像,我建议您加载一次并隐藏它们,而不是每次都创建图像元素 "on the fly"。这样你就可以设置它们的可见性而不是重写内部 html...