# 概念阐释 # 实例 # 相关内容 # 问题 [练习题](https://www.codecademy.com/courses/build-interactive-websites/projects/piano-keys) 🌟 ![](http://image.harryrou.wiki/2023-05-24-CleanShot%202023-05-22%20at%2007.00.33%402x.png) # 问题答案 ```js // The keys and notes variables store the piano keys const keys = ['c-key', 'd-key', 'e-key', 'f-key', 'g-key', 'a-key', 'b-key', 'high-c-key', 'c-sharp-key', 'd-sharp-key', 'f-sharp-key', 'g-sharp-key', 'a-sharp-key']; const notes = []; // 遍历keys的数组值,设值为key,执行函数访问key所代表的id值,推送到notes数组中,notes数组值相当于执行访问每一个id的任务 keys.forEach(function(key){ notes.push(document.getElementById(key)); }) // Write named functions that change the color of the keys below //1. 在第二个评论后,创建一个名为keyPlay的函数,当按下键时更改键的背景颜色。在函数中一定要使用.target属性,因为在这种情况下目标正在被修改。 let keyPlay = (event) => { event.target.style.backgroundColor = 'pink'; }; //2. 接下来,创建一个名为keyReturn的函数,当鼠标释放在元素上时,将键的背景颜色返回到默认颜色,即空字符串''。一定要使用.target属性。 let keyReturn = (event) => { event.target.style.backgroundColor = ''; }; // Write a named function with event handler properties //3. 现在你已经创建了两个改变关键元素颜色的函数,你必须将它们分配为事件处理程序属性的值。创建一个命名函数,暂时留下代码块为空。这个函数将在后面用于为键分配事件,所以它应该有一个参数——你可以称之为note。 //4. 在函数内部,创建一个事件处理程序,当任何音符上发生mousedown事件时,将keyPlay作为事件处理程序运行。 //5. 在函数内部,创建第二个事件处理程序属性,当任何音符上触发mouseup事件时运行keyReturn。 //?????只能用onevent的写法? let eventAssignment = (note) => { note.addEventListener('mousedown',keyPlay); // note.onmousedown = function(){ // keyPlay(event); // } note.addEventListener('mouseup',keyReturn); // note.onmouseup = function(){ // keyReturn(event); // } }; // Write a loop that runs the array elements through the function //6. 在代码的开头,我们对键数组和空音符数组进行变量名分配。还有一个函数循环遍历键数组,并将键元素推送到音符数组中以分配变量名。现在,您必须创建一个.forEach循环,它将通过eventAssignment分配函数传递音符数组中的元素。 // 现在,程序知道当每个钢琴键上触发mousedown或mouseup事件时该怎么做了。运行你的代码,看看它是如何工作的! notes.forEach(eventAssignment); // These variables store the buttons that progress the user through the lyrics let nextOne = document.getElementById('first-next-line'); let nextTwo = document.getElementById('second-next-line'); let nextThree = document.getElementById('third-next-line'); let startOver = document.getElementById('fourth-next-line'); // This variable stores the '-END' lyric element let lastLyric = document.getElementById('column-optional'); // These statements are "hiding" all the progress buttons, but the first one nextTwo.hidden = true; nextThree.hidden = true; startOver.hidden= true; // Write anonymous event handler property and function for the first progress button //8. 接下来,下面的歌曲框中有代表进度按钮的变量,允许学生推进钢琴。nextOne、nextTwo、nextThree和startOver会改变歌曲的歌词和乐符,帮助学生跟着弹奏。在歌曲的开头,学生只需要使用nextOne按钮。因此,其他按钮的.hidden属性被赋值为true。现在,您必须在所有进度按钮上创建事件。首先,在nextOne元素上创建一个点击事件的事件处理程序属性。 // 9.开始修改歌曲盒子,您必须首先切换进度按钮。使用匿名事件处理函数,对在点击nextOne按钮后出现的按钮进行以下更改:通过更改.hidden属性使nextTwo按钮出现,以显示nextTwo按钮。通过更改.hidden属性来隐藏nextOne按钮,以隐藏nextOne按钮。 // 接下来,当nextOne上发生点击事件时,必须更改指导钢琴学生演奏歌曲的音符。将以下更改添加到nextOne事件处理程序函数中,以便在单击按钮时更改音符。将ID为letter-note-five的元素内容更改为D。将ID为letter-note-six的元素内容更改为C. nextOne.addEventListener('click',function(){ nextOne.hidden = true; nextTwo.hidden = false; document.getElementById('letter-note-five').innerHTML = 'D'; document.getElementById('letter-note-six').innerHTML = 'C'; }); // Write anonymous event handler property and function for the second progress button //11. 在按钮元素上创建一个名为nextTwo的点击事件处理程序属性。然后将该属性分配给一个匿名事件处理程序函数的值。 //12. 当点击nextTwo按钮时,对该按钮进行以下更改:通过更改.hidden属性来显示nextThree按钮,使nextThree按钮出现。通过更改.hidden属性来隐藏nextTwo按钮,使nextTwo按钮隐藏。 //13. 当按钮被点击时,请对函数中的歌词进行以下更改:将ID为word-five的元素内容更改为DEAR。将ID为word-six的元素内容更改为FRI-。 //14. 现在你有了歌词“HAP-PY BIRTH-DAY DEAR FRI-”。要完成这一行,你必须在钢琴下方的歌曲框中添加“-END”。“-END”元素存储在lastLyric变量中。在nextTwo的事件处理程序函数中添加一个语句,将lastLyric的display属性更改为'inline-block'。 nextTwo.addEventListener('click',function(){ nextTwo.hidden = true; nextThree.hidden = false; document.getElementById('word-five').innerHTML = 'DEAR'; document.getElementById('word-six').innerHTML = 'FRI-'; document.getElementById('letter-note-three').innerHTML = 'G'; document.getElementById('letter-note-four').innerHTML = 'E'; document.getElementById('letter-note-five').innerHTML = 'C'; document.getElementById('letter-note-six').innerHTML = 'B'; lastLyric.style.display = 'inline-block'; }); // Write anonymous event handler property and function for the third progress button //16. 在nextThree元素上创建一个带有点击事件的事件处理程序属性。 //17. 通过改变.hidden属性使startOver按钮出现,来显示startOver按钮(显现为flaseflase)。通过改变.hidden属性来隐藏nextThree按钮,使nextThree按钮消失。 // 20现在你有歌词“生日快乐!-结束”——这肯定不对!要完成这一行,你必须在歌曲框中删除“-结束”。在nextThree的事件处理程序函数中添加一个语句,将lastLyric的显示属性改回“none”。 nextThree.addEventListener('click',function(){ startOver.hidden = false; nextThree.hidden = true; document.getElementById('word-one').innerHTML = 'HAP-'; document.getElementById('word-two').innerHTML = 'PY'; document.getElementById('word-three').innerHTML = 'BIRTH-'; document.getElementById('word-four').innerHTML = 'DAY'; document.getElementById('word-five').innerHTML = 'TO'; document.getElementById('word-six').innerHTML = 'YOU!'; document.getElementById('letter-note-one').innerHTML = 'F'; document.getElementById('letter-note-two').innerHTML = 'F'; document.getElementById('letter-note-three').innerHTML = 'E'; document.getElementById('letter-note-four').innerHTML = 'C'; document.getElementById('letter-note-five').innerHTML = 'D'; document.getElementById('letter-note-six').innerHTML = 'C'; lastLyric.style.display = 'none'; }); // This is the event handler property and function for the startOver button startOver.onclick = function() { nextOne.hidden = false; startOver.hidden = true; document.getElementById('word-one').innerHTML = 'HAP-'; document.getElementById('letter-note-one').innerHTML = 'G'; document.getElementById('word-two').innerHTML = 'PY'; document.getElementById('letter-note-two').innerHTML = 'G'; document.getElementById('word-three').innerHTML = 'BIRTH-'; document.getElementById('letter-note-three').innerHTML = 'A'; document.getElementById('word-four').innerHTML = 'DAY'; document.getElementById('letter-note-four').innerHTML = 'G'; document.getElementById('word-five').innerHTML = 'TO'; document.getElementById('letter-note-five').innerHTML = 'C'; document.getElementById('word-six').innerHTML = 'YOU!'; document.getElementById('letter-note-six').innerHTML = 'B'; } ``` # 参考资料 - [[js Iterators 数组函数内置对象 forEach()]]是传递函数而不是调用函数