function playGreen(){
var audio = document.getElementById("audioG");
audio.play();
}
function playRed(){
var audio = document.getElementById("audioR");
audio.play();
}
function playYellow(){
var audio = document.getElementById("audioY");
audio.play();
}
function playBlue(){
var audio = document.getElementById("audioB");
audio.play();
}它将按原样运作。但似乎我应该可以把这四个函数简化成一个变量?我能得到一些关于这方面的指导吗,还有任何其他的指点。仅从javascript其余部分的伪逻辑开始。
<div class="gameWrapper">
<div class="backPlate">
<div class="pushPad green" onclick="playGreen()" >
<audio preload="auto" id="audioG" data-pad="1"> <!-- upper left -->
<source src="https://s3.amazonaws.com/freecodecamp/simonSound1.mp3" type="audio/mpeg"/>
</audio>
</div>
<div class="pushPad red" onclick="playRed()" >
<audio preload="auto" id="audioR" data-pad="2"> <!-- upper right -->
<source src="https://s3.amazonaws.com/freecodecamp/simonSound2.mp3" type="audio/mpeg"/>
</audio>
</div>
<div class="pushPad yellow" onclick="playYellow()" >
<audio preload="auto" id="audioY" data-pad="3"> <!-- lower left -->
<source src="https://s3.amazonaws.com/freecodecamp/simonSound3.mp3" type="audio/mpeg"/>
</audio>
</div>
<div class="pushPad blue" onclick="playBlue()" >
<audio preload="auto" id="audioB" data-pad="4"> <!-- lower right -->
<source src="https://s3.amazonaws.com/freecodecamp/simonSound4.mp3" type="audio/mpeg"/>
</audio>
</div>
<div class="startCircle">
<h3>Shall we<br>play a game?</h3>
</div>
<div class="centerCircle"></div>
</div>
</div>发布于 2017-06-08 22:01:53
重复代码通常被认为是一种不好的做法,因为对一个版本进行更改可能需要对所有版本进行更改。如果设计决策是本地化的,并且接近它们所做的,那么维护代码就更容易了。
幸运的是,摆脱playCOLOR函数中的枯燥代码是很容易的。您只需要注意,这四个元素之间唯一的区别是元素的颜色和id。
使用对象
要做到这一点,最简洁的方法之一是使用对象:
const audoByColor = {
"red": document.getElementById("audioR"),
"green": document.getElementById("audioG"),
"blue": document.getElementById("audioB"),
"yellow": document.getElementById("audioY")
};这个{ ... };被称为对象,[color]部件请求作为参数传递的相应color键的值。对象很擅长关联特定的keys (“红色”、“绿色”、.)特定的values ("audoR“、"audioG”、.)。
然后,在蓝色元素中,您可以将:
<div class="pushPad blue" onclick="audoByColor['blue'].play()">使用开关语句
您可以使用开关语句实现类似的效果:
function getAudioByColor(color) {
switch (color) {
case "red":
return document.getElementById("audioR");
case "green":
return document.getElementById("audioG");
case "blue":
return document.getElementById("audioB");
case "yellow":
return document.getElementById("audioY");
default:
return null;
};
}请注意,有些人对开关语句不屑一顾,因为它们可能导致范围错误和忘记break或return的问题。但是,它们带来的好处是,您可以很容易地指定默认情况。
通过使用if else块列表,可以以更安全的方式实现与开关语句相同的效果:
function getAudioByColor(color) {
if (color === "red") {
return document.getElementById("audioR");
}
else if (color === "green") {
return document.getElementById("audioG");
}
else if (color === "blue") {
return document.getElementById("audioB");
}
else if (color === "yellow") {
return document.getElementById("audioY");
}
else {
return null;
}
}我觉得这有点麻烦,但对于阅读您的代码的人来说,这可能是最明显的。
发布于 2017-06-08 21:39:04
我建议从HTML文档中删除内联onclick事件处理程序,以更清晰地分离标记和逻辑/ JavaScript,类似于分离标记和样式/ CSS的方式。
然后,可以使用以下几行代码添加所有事件处理程序:
document.querySelectorAll('.pushPad').forEach(pad => {
let audio = pad.querySelector('audio');
pad.addEventListener('click', event => audio.play());
});更好的设计可能会在彩色按钮上有data-pad属性,而不是在隐藏的<audio>元素上,引入pad和音频源之间的映射,而不是利用web音频API。在UI中使用<svg>形状而不是重样式的<div>s,可能会进一步简化您的标记。
发布于 2017-06-09 16:24:47
一种选择是做这样的事情:
function play(node) {
var audio = node.getElementsByTagName('audio')[0];
audio.play();
}
<div class="pushPad green" onclick="play(this)" >
<audio preload="auto" id="audioG" data-pad="1"> <!-- upper left -->
<source src="https://s3.amazonaws.com/freecodecamp/simonSound1.mp3" type="audio/mpeg"/>
</audio>
</div>但是,我不太喜欢这样嵌套隐藏的音频元素,我会将音频节点放在文档的底部,并执行如下操作:
function play(node) {
var audioId = node.attributes['data-audio-id'].value;
console.log('audioId', audioId);
var audio = document.getElementById(audioId);
audio.play();
}
<div class="pushPad green" onclick="play(this)" ></div>
... At the bottom of my document.
<audio preload="auto" id="audioG" data-pad="1"> <!-- upper left -->
<source src="https://s3.amazonaws.com/freecodecamp/simonSound1.mp3" type="audio/mpeg"/>
</audio>https://codereview.stackexchange.com/questions/165300
复制相似问题