为什么这个 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...
编辑:我遇到了一个新问题。 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...