Javascript for循环的当前迭代返回未定义,函数的返回未定义
如果没有jQuery和co这样的框架,我目前几乎不会关注普通JavaScript。不幸的是,我知道了两个错误,这两个错误在过去几天一直困扰着我。我已经在互联网上搜索过了,但我认为这些错误比在网上找到一个通用的解决方案或解决方法要个人化得多 这是我的index.htlml:Javascript for循环的当前迭代返回未定义,函数的返回未定义,javascript,for-loop,Javascript,For Loop,如果没有jQuery和co这样的框架,我目前几乎不会关注普通JavaScript。不幸的是,我知道了两个错误,这两个错误在过去几天一直困扰着我。我已经在互联网上搜索过了,但我认为这些错误比在网上找到一个通用的解决方案或解决方法要个人化得多 这是我的index.htlml: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="v
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Songs</title>
</head>
<body>
<div id="body-inner">
<div class="playlist"></div> <br>
<div class="song">
<div class="current"></div> <br>
<span class="time"></span>
<button class="play">Play</button>
<button class="pause">Pause</button>
</div>
</div>
<script src="main.js"></script>
</body>
</html>
歌曲
玩
暂停
下面是我的main.js:
const [playlistOut, currentOut, timeOut] = [
document.querySelector(".playlist"),
document.querySelector(".current"),
document.querySelector(".time")
];
// Create the App Object
let app = {
playlists: {
playlistSongs: [
"Backseat",
"Unforgettable",
"BlueSkies",
"Thunder",
"Overflow",
"Up&Down",
"DoMyThing",
"Heroes",
"Miracles",
"CakeByTheOcean",
"InTheEnd",
"Feel"
]
},
songDurations: {
Backseat: 195,
Unforgettable: 252,
BlueSkies: 323,
Thunder: 182,
Overflow: 249,
UpDown: 154,
DoMyThing: 534,
Heroes: 420,
Miracles: 236,
CakeByTheOcean: 379,
InTheEnd: 231,
Feel: 432
},
start: () => {
showPlaylist(app.playlists.playlistSongs);
clickSong();
}
};
window.onload = app.start;
let test = {
minutes: false,
seconds: false
};
// Configure Timer
function startTimer(duration, display) {
var timer = duration,
minutes,
seconds;
if (duration != isNaN) {
var timer = duration,
minutes,
seconds;
interval = setInterval(() => {
minutes = parseInt(timer / 60, 10);
seconds = parseInt(timer % 60, 10);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
display.textContent = minutes + ":" + seconds;
test.minutes = minutes;
test.seconds = seconds;
console.log("Minutes Func: " + minutes);
console.log("Seconds Func: " + seconds);
if (--timer < 0) {
timer = 0;
}
}, 1000);
} else {
var error = "The given duration is not a number.";
console.log(error);
alert(error);
}
console.log("Inside Func: " + minutes);
return { success: true, min: minutes, secs: seconds };
}
console.log("test.minutes: " + test.minutes);
console.log("test.seconds: " + test.seconds);
// Init Timer
let timerfunc = startTimer(60, timeOut);
console.log(timerfunc.min);
// Manage Play and Pause Buttons
document.querySelector(".pause").addEventListener("click", () => {
clearInterval(interval);
});
document.querySelector(".play").addEventListener("click", () => {
let currentDuration = timerfunc.min * 60 + timerfunc.secs;
console.log(currentDuration);
startTimer(currentDuration, timeOut);
});
// Show Playlist
function showPlaylist(playlist) {
if (playlist.length > 0) {
var constructor = {
content: new Array()
};
for (var i = 0; i < playlist.length; i++) {
constructor.content.push(
'<a href="#" id="' +
playlist[i] +
'" class="song">' +
playlist[i] +
"</a><br>"
);
}
playlistOut.innerHTML = constructor.content.join("");
return true;
} else {
var error = "There is no playlist existing with this name.";
console.log(error);
return false;
}
}
// Get the Time of the Element Clicked and Start the Timer
/* FIXME FIXME FIXME
songElements[i] returns undefined in l. 109 ff.
FIXME FIXME FIXME */
function clickSong() {
var songElements = document.querySelectorAll(".song");
for (var i = 0; i < songElements.length; i++) {
songElements[i].addEventListener("click", function(e) {
e.preventDefault;
console.log(songElements[i].id);
var songDuration = app.songDurations.songElements[i].id;
startTimer(songDuration, timeOut);
currentOut.innerHTML = "Currently Playing: " + songElements[i].id;
});
}
}
const[播放输出,当前输出,超时]=[
document.querySelector(“播放列表”),
文档查询选择器(“当前”),
文档查询选择器(“时间”)
];
//创建应用程序对象
让应用程序={
播放列表:{
播放歌曲:[
“后座”,
“难忘”,
“蓝调”,
“雷声”,
“溢出”,
“上下”,
“DoMyThing”,
“英雄”,
“奇迹”,
“Cakebytheoan”,
“最后”,
“感觉”
]
},
歌曲持续时间:{
后座:195,
难忘:252,
蓝调:323,
雷霆:182,
溢位:249,
向上向下:154,
地址:534,
英雄:420,
奇迹:236,
Cakebytheoan:379,
最终:231,
感觉:432
},
开始:()=>{
showPlaylist(应用程序播放列表、播放歌曲);
点击歌曲();
}
};
window.onload=app.start;
让测试={
会议记录:错,
秒:假
};
//配置定时器
功能启动计时器(持续时间、显示){
var定时器=持续时间,
会议记录,
秒;
如果(持续时间!=isNaN){
var定时器=持续时间,
会议记录,
秒;
间隔=设置间隔(()=>{
分钟=parseInt(计时器/60,10);
秒=parseInt(计时器%60,10);
分钟=分钟<10?“0”+分钟:分钟;
秒=秒<10?“0”+秒:秒;
display.textContent=分钟+“:”+秒;
test.minutes=分钟;
test.seconds=秒;
console.log(“分钟函数:+Minutes”);
console.log(“秒函数:+Seconds”);
如果(--定时器<0){
定时器=0;
}
}, 1000);
}否则{
var error=“给定的持续时间不是一个数字。”;
console.log(错误);
警报(错误);
}
控制台日志(“内部函数:+分钟);
返回{success:true,min:minutes,secs:seconds};
}
控制台日志(“test.minutes:+test.minutes”);
日志(“test.seconds:+test.seconds”);
//初始化计时器
设timerfunc=startTimer(60,超时);
console.log(timerfunc.min);
//管理播放和暂停按钮
document.querySelector(“.pause”).addEventListener(“单击”,()=>{
间隔时间;
});
document.querySelector(“.play”).addEventListener(“单击”,()=>{
让currentDuration=timerfunc.min*60+timerfunc.secs;
console.log(currentDuration);
startTimer(当前持续时间、超时);
});
//显示播放列表
功能显示播放列表(播放列表){
如果(playlist.length>0){
变量构造函数={
内容:新数组()
};
对于(变量i=0;i”
);
}
playlayout.innerHTML=constructor.content.join(“”);
返回true;
}否则{
var error=“没有具有此名称的播放列表。”;
console.log(错误);
返回false;
}
}
//获取单击元素的时间并启动计时器
/*修理我修理我修理我
songElements[i]返回l.109 ff中未定义的值。
修理我修理我修理我*/
函数clickSong(){
var songElements=document.queryselectoral(“.song”);
对于(var i=0;i
正如您所见,该应用程序是关于歌曲播放列表的,您应该能够从播放列表中动态选择歌曲,并能够手动启动和停止歌曲第53行没有返回想要的值,因此脚本可以在用户再次手动停止后获得启动计时器的当前时间(以秒为单位)。为了更好地理解变量的作用域,我已经用一堆console.log粘贴了代码,但我仍然无法解决问题
下一个更重要的错误可以在函数clickSong()中的第133行找到。我正在获取其中包含.song类的所有元素,并将它们返回到节点列表中。下一步,我将在所述节点列表中运行for循环,以在单击的exact元素上应用click eventHandler。但问题已经存在:我无法单击该项,实际上是for循环第136行的当前迭代总是返回未定义的。很遗憾,我根本不知道如何解决这个问题
你有什么想法吗?或者你可能经历过类似的情况吗?我很高兴能得到帮助
提前感谢您,J0nny问题是,在任何单击事件触发回调之前,
i
变量将达到for
循环的结束值。因此,无论发生哪个单击事件,回调都将使用超出范围的i
值
通过使用let
而不是var
,您可以很容易地解决这个问题,因为这将为每次迭代创建一个新的变量实例,并且将在异步回调中引用该实例
for (let i = 0; i < songElements.length; i++) {
您的app.songDurations
对象没有songElements
属性,因此无法使用。您打算这样做吗
app.songDurations[songElements[i].id]
我改变了很多,所以只要看看代码,看看有什么改变 HTML
歌曲
app.songDurations[songElements[i].id]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Songs</title>
</head>
<body>
<div id="body-inner">
<div class="playlist"></div> <br>
<div class="controls">
<div class="current"></div> <br>
<span class="time"></span>
<button class="play">Play</button>
<button class="pause">Pause</button>
</div>
</div>
<script src="main.js"></script>
</body>
</html>
const [playlistOut, currentOut, timeOut] = [
document.querySelector(".playlist"),
document.querySelector(".current"),
document.querySelector(".time")
];
// Create the App Object
let app = {
playList: [
"Backseat",
"Unforgettable",
"BlueSkies",
"Thunder",
"Overflow",
"Up&Down",
"DoMyThing",
"Heroes",
"Miracles",
"CakeByTheOcean",
"InTheEnd",
"Feel"
],
songDurations: {
Backseat: 195,
Unforgettable: 252,
BlueSkies: 323,
Thunder: 182,
Overflow: 249,
UpDown: 154,
DoMyThing: 534,
Heroes: 420,
Miracles: 236,
CakeByTheOcean: 379,
InTheEnd: 231,
Feel: 432
},
start: () => {
renderPlayList(app.playList);
clickSong();
}
};
window.onload = app.start;
let [playListInterval, currentMinute, currentSecond] = [0, 0, 0];
// Configure Timer
function startTimer(duration, display) {
currentMinute = parseInt(duration / 60, 10);
currentSecond = parseInt(duration % 60, 10);
if (!isNaN(duration)) {
let timer = duration;
playListInterval = setInterval(() => {
currentMinute = parseInt(timer / 60, 10);
currentSecond = parseInt(timer % 60, 10);
const minutes = currentMinute < 10 ? "0" + currentMinute : currentMinute;
const seconds = currentSecond < 10 ? "0" + currentSecond : currentSecond;
display.textContent = minutes + ":" + seconds;
if (--timer < 0) {
timer = 0;
}
}, 1000);
} else {
const error = "The given duration is not a number.";
console.log(error);
alert(error);
}
}
// Manage Play and Pause Buttons
document.querySelector(".pause").addEventListener("click", () => {
if (playListInterval !== 0) {
clearInterval(playListInterval);
playListInterval = 0;
}
});
document.querySelector(".play").addEventListener("click", () => {
let currentDuration = currentMinute * 60 + currentSecond;
startTimer(currentDuration, timeOut);
});
// Show Playlist
function renderPlayList(playlist) {
if (playlist.length > 0) {
const content = [];
for (let i = 0; i < playlist.length; i++) {
content.push(
'<a href="#" id="' +
playlist[i] +
'" class="song">' +
playlist[i] +
"</a><br>"
);
}
playlistOut.innerHTML = content.join("");
return true;
} else {
const error = "There is no playlist existing with this name.";
console.log(error);
return false;
}
}
// Get the Time of the Element Clicked and Start the Timer
function clickSong() {
const songElements = document.querySelectorAll(".song");
for (let i = 0; i < songElements.length; i++) {
const currentElement = songElements[i];
currentElement.addEventListener("click", function (event) {
event.preventDefault();
const songDuration = app.songDurations[currentElement.id];
if (playListInterval !== 0) {
clearInterval(playListInterval);
playListInterval = 0;
}
startTimer(songDuration, timeOut);
currentOut.innerHTML = "Currently Playing: " + currentElement.id;
});
}
}