如何在JavaScript中访问父元素内的类并解决querySelectorAll相关问题?
需求说明
我需要用JavaScript动态修改3个不同ID元素内的.spacer类元素的样式属性,之前在类似问题里找到的方案不完全匹配。我熟悉document.getElementById和document.getElementsByClassName,但不知道怎么正确编写访问每个ID下指定类的语法。
示例代码
HTML结构
<div id="col1" name="col1"> <div (or image, etc.)></div> <div class="spacer"></div> <div (or image, etc.)></div> <div class="spacer"></div> <div (or image, etc.)></div> </div> <div id="col2" name="col2"> <div (or image, etc.)></div> <div class="spacer"></div> <div (or image, etc.)></div> <div class="spacer"></div> <div (or image, etc.)></div> </div>
CSS实现方式(参考)
如果用CSS静态设置,代码如下:
#col1 .spacer{ height:10px; } #col2 .spacer{ height:15px; } /* ...其他列的设置 */
遇到的问题与疑问
- 有人提供了这段代码,但还没生效,想确认语法:
var col1Spacers = document.querySelectorAll('#col1 .spacer'); col1Spacers.forEach(function(spacer) { spacer.style.height = '10px'; });
请问var col1Spacers = document.querySelectorAll('#col1 .spacer');是不是创建了一个名为col1Spacers的数组?
- 我定义了3个querySelectorAll的结果,想把它们存入数组,但出现异常:
var col1spacer = document.querySelectorAll('#col1 .spacer'); alert(col1spacer.length); // 弹出11 var col2spacer = document.querySelectorAll('#col2 .spacer'); alert(col2spacer.length); // 弹出10 var col3spacer = document.querySelectorAll('#col3 .spacer'); alert(col3spacer.length); // 弹出9 const columnSpacer = ['col1spacer', 'col2spacer', 'col3spacer']; alert(columnSpacer[0].length + ', ' + columnSpacer[1].length + ', ' + columnSpacer[2].length); // 弹出10,10,10
为什么最后一个alert的结果不对?能不能创建包含不同长度的querySelectorAll结果的数组?
解答
关于querySelectorAll的返回值
document.querySelectorAll()返回的不是数组,而是NodeList(节点列表)——一个类数组对象。现代浏览器中NodeList原生支持forEach方法,可以直接遍历;如果需要使用数组的map/filter等方法,可将其转为数组:
// 方法1:使用Array.from const col1SpacersArray = Array.from(document.querySelectorAll('#col1 .spacer')); // 方法2:使用扩展运算符 const col1SpacersArray = [...document.querySelectorAll('#col1 .spacer')];
之前代码未生效的常见原因:代码执行时DOM还未完全加载。解决方法是把代码放在DOMContentLoaded事件监听里,或者将脚本放在页面底部(</body>标签之前):
document.addEventListener('DOMContentLoaded', function() { var col1Spacers = document.querySelectorAll('#col1 .spacer'); col1Spacers.forEach(function(spacer) { spacer.style.height = '10px'; }); });
关于数组存储的问题
你的错误在于把变量名的字符串存入了数组,而不是变量本身。['col1spacer', 'col2spacer', 'col3spacer']里的每个元素都是字符串,字符串的length是它的字符数(比如'col1spacer'有10个字符,所以length是10)。
正确的写法是直接把变量存入数组:
var col1spacer = document.querySelectorAll('#col1 .spacer'); var col2spacer = document.querySelectorAll('#col2 .spacer'); var col3spacer = document.querySelectorAll('#col3 .spacer'); const columnSpacer = [col1spacer, col2spacer, col3spacer]; alert(columnSpacer[0].length + ', ' + columnSpacer[1].length + ', ' + columnSpacer[2].length); // 会弹出11,10,9
这样数组里的每个元素都是NodeList对象,各自保留自己的length值,完全支持不同长度的元素共存。
内容的提问来源于stack exchange,提问作者CJ Reynolds

