Javascript 问题是:无法读取属性';播放';未定义的
事实上,我一直在解决这个问题。它给我这个错误“uncaughttypeerror:无法读取未定义的属性‘play’”。当我使用foreach循环时,一切都很顺利,但使用normal for循环会产生这个错误,我不知道为什么 下面是使用javascript的代码Javascript 问题是:无法读取属性';播放';未定义的,javascript,html,Javascript,Html,事实上,我一直在解决这个问题。它给我这个错误“uncaughttypeerror:无法读取未定义的属性‘play’”。当我使用foreach循环时,一切都很顺利,但使用normal for循环会产生这个错误,我不知道为什么 下面是使用javascript的代码 window.addEventListener("load", function () { const pads = document.querySelectorAll(".pads div"); const sounds
window.addEventListener("load", function () {
const pads = document.querySelectorAll(".pads div");
const sounds = document.querySelectorAll(".sound");
var numberOfPads = document.querySelectorAll(".pads div").length;
for (var i = 0; i < numberOfPads; i++) {
pads[i].addEventListener("click", function () {
sounds[i].play();
});
}
});
window.addEventListener(“加载”,函数(){
const pads=document.queryselectoral(“.pads div”);
const sounds=document.queryselectoral(“.sound”);
var numberOfPads=document.queryselectoral(“.pads div”).length;
对于(变量i=0;i
HTML代码:
<body>
<section class="app">
<header>
<h1>Beatmaker</h1>
</header>
<div class="visual">
<div class="pads">
<div class="pad1">
<audio class="sound" src="sounds/bubbles.mp3">
</audio>
</div>
<div class="pad2">
<audio class="sound" src="sounds/clay.mp3">
</audio>
</div>
<div class="pad3">
<audio class="sound" src="sounds/confetti.mp3">
</audio>
</div>
</div>
<div class="pads">
<div class="pad4">
<audio class="sound" src="sounds/glimmer.mp3">
</audio>
</div>
<div class="pad5">
<audio class="sound" src="sounds/moon.mp3">
</audio>
</div>
<div class="pad6">
<audio class="sound" src="sounds/ufo.mp3">
</audio>
</div>
</div>
</div>
</section>
</body>
打手
这是一个棘手的问题。发生这种情况的原因是i
是函数作用域,这意味着同一个i
用于函数内的任何点。这也适用于未来的事情。循环修改i
,循环完成后,i
将比最大值高1
让我们按照事情发生的顺序,一步一步地完成这个过程。为了清楚起见:我看到6个div,因此我们有从0到5(包括)的有效值I
- 您的
事件处理程序执行:load
为0。循环正文运行是因为0小于6i
- 语句
以pads[i].addEventListener(“click”,…)
i==0执行
为1。循环体运行是因为1小于6i
- 语句
以pads[i].addEventListener(“click”,…)
i==1执行
是5。循环体运行是因为5小于6i
- 语句
以pads[i].addEventListener(“click”,…)
i==5执行
是6。你的循环体不会运行,因为6不小于6i
- 单击一个div,比如说
。pad4
处理程序运行(当click
为3时设置的处理程序)i
- 然而,由于我们在这里总是谈论相同的
,i
现在是6(参见前面的最后一步!)i
- 行
运行,试图访问声音[i].play()
声音[6]
- 由于
未定义,因此无法读取其属性sounds[6]
,因此会出现错误play
forEach
一起工作的原因是它使用回调,这意味着您在其中访问的i
是回调函数的参数,它是特定函数调用的本地参数。因此,您每次都会得到一个新的i
,它在将来也会保持其值(它永远不会被修改)。通过这种方式,您基本上可以得到6个不同的i
s,而不是1个i
随时间改变其值
如果要继续使用for
循环,必须使用let
而不是var
:
for(设i=0;i
这是因为let
创建了一个块范围的变量。我知道现在这有点让人困惑,因为I
仍在被修改,但这是由于for
与let
结合使用的一种特殊的便利行为:它实际上在这里创建了两个I
s,每次都会修改一个(您在for(…)
参数中看到的那一个)以及在每次迭代中从修改后的副本创建的副本(您在循环体中看到的副本)
如果您对此感到困惑,另一种(更符合逻辑)解决问题的方法是手动将i
分配给循环内的块范围副本:
<代码>窗口.addEventListener(“加载”,函数(){
const pads=document.queryselectoral(“.pads div”);
const sounds=document.queryselectoral(“.sound”);
var numberOfPads=document.queryselectoral(“.pads div”).length;
对于(变量i=0;iconst
来强调它不会被修改,甚至不能被修改,但是let
也可以,只是var
不会!)