Vanilla JS实现简易钢琴时querySelector操作data-*属性报错排查
问题分析与解决方案
嘿,我来帮你搞定这个钢琴小项目的问题!咱们一步步拆解:
1. 为什么会出现选择器语法错误?
你遇到的Failed to execute 'querySelector' on 'Document': 'audio[data-key=100]' is not a valid selector错误,核心原因是CSS属性选择器中,数字开头的属性值需要用引号包裹。
在你的代码里,querySelector(audio[data-key=${tempVal}])生成的选择器是audio[data-key=100],这种写法对于数字开头的属性值是不符合CSS选择器规范的。你需要把数值用引号括起来,改成:
audioKeyProp[tempVal] = document.querySelector(`audio[data-key="${tempVal}"]`);
这样生成的选择器就是audio[data-key="100"],这才是合法的格式。
2. 隐藏的小问题:未初始化对象
你定义了var audioKeyProp;但没有给它初始值,它默认是undefined。直接给undefined添加属性会导致后续报错,所以要把它初始化成一个空对象:
var audioKeyProp = {};
3. 关于data-key属性的疑问
完全可以在<div>和<audio>(甚至任何HTML元素)上使用data-key属性!data-*是HTML5的自定义数据属性,专门用来给元素存储自定义的元数据,所有HTML元素都支持这个特性,这完全符合规范,你不用担心这个问题。
修正后的完整JS代码
let keyArr = document.querySelectorAll(".musicKey"); var audioKeyProp = {}; // 初始化空对象 keyArr.forEach(function(item) { let tempVal = item.getAttribute('data-key'); // 给data-key的数值添加引号,修正选择器 audioKeyProp[tempVal] = document.querySelector(`audio[data-key="${tempVal}"]`); // 调试用 console.log(audioKeyProp[tempVal]); });
这样修改后,你的选择器就能正常匹配到对应的audio元素,对象也能正确存储关联关系了。之后你就可以继续添加按键监听事件,按下对应按键时调用audioKeyProp[对应key].play()来播放声音啦!
内容的提问来源于stack exchange,提问作者sandy
相关产品推荐
相关产品推荐

