window.getComputedStyle方法 和 document.getElementsByClassName获取的样式有何不一样?document.getElementsByClassName和document.querySelectorAll返回的节点又有哪里不一样?
一、window.getComputedStyle方法 和 document.getElementsByClassName获取的样式有何不一样?
(一)用途与功能差异
-
document.getElementsByClassName- 用途:用于通过类名获取元素集合(返回
HTMLCollection),不直接涉及样式操作 - 返回值:动态的 DOM 元素集合,仅包含符合条件的元素引用,需遍历元素后单独处理样式。
- 用途:用于通过类名获取元素集合(返回
-
window.getComputedStyle- 用途:获取单个元素的所有计算样式(包括行内样式、CSS 样式表、继承样式和浏览器默认样式),返回
CSSStyleDeclaration对象 - 返回值:包含元素最终生效的样式属性和值的只读对象,支持通过属性名或
getPropertyValue()访问具体样式值
- 用途:获取单个元素的所有计算样式(包括行内样式、CSS 样式表、继承样式和浏览器默认样式),返回
(二)样式来源与实时性
-
样式来源
getElementsByClassName间接获取的样式:
需通过遍历元素后访问element.style,但此方式仅能读取行内样式(如<div style="color:red">),无法获取 CSS 样式表中定义的样式getComputedStyle获取的样式:
整合所有来源的样式,包括行内、CSS 样式表、继承和默认样式,返回最终应用的实时计算结果
-
实时性方面
getElementsByClassName返回的集合:
是动态的,若 DOM 中新增/删除符合类名的元素,集合会自动更新getComputedStyle返回的样式对象:
是实时更新的,若元素样式发生改变(如通过 JavaScript 动态修改),再次访问会反映最新值
(三)读写能力与兼容性
-
读写能力
element.style(通过getElementsByClassName遍历后访问):- 可读可写,直接修改行内样式(如
element.style.color = 'red') - 无法读取非行内样式,且可能因 CSS 优先级(如
!important)导致修改无效
- 可读可写,直接修改行内样式(如
getComputedStyle:- 只读,无法通过此方法修改样式,仅用于获取当前生效的样式值
-
浏览器兼容性
getElementsByClassName:
所有现代浏览器均支持,但返回的HTMLCollection需手动遍历处理getComputedStyle:- 支持现代浏览器(Chrome、Firefox、Safari、Edge)及 IE9+
- 旧版 IE(IE8 及以下)需使用
element.currentStyle替代
二、document.getElementsByClassName和document.querySelectorAll返回的节点又有哪里不一样?
代码demo:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Class选择器对比调试</title>
<style>
.debug-box {
border: 1pxsolid#ccc;
padding: 20px;
margin: 10px;
}
.sample-element {
background-color: #f0f0f0;
margin: 5px;
padding: 10px;
}
</style>
</head>
<body>
<div class="controls">
<button onclick="compareSelectors()">运行对比测试</button>
<button onclick="addNewElement()">添加新元素</button>
<button onclick="addStyle()">改变颜色,你可以看到控制台打印的对象的颜色属性都得到了更新</button>
</div>
<!-- 测试用元素 -->
<div class="sample-element">元素 1</div>
<div class="sample-element">元素 2</div>
<div class="sample-element special">元素 3 (带special类)</div>
<div class="debug-box">
<h3>实时对比结果:</h3>
<pre id="output"></pre>
</div>
<script>
functionlog(message) {
constoutput = document.getElementById('output');
output.textContent += message + '\n';
}
functionclearLog() {
document.getElementById('output').textContent = '';
}
// 获取元素集合
constbyClassName = document.getElementsByClassName('sample-element');
constbyQueryAll = document.querySelectorAll('.sample-element');
functioncompareSelectors() {
clearLog();
// 类型对比
log('=== 类型对比 ===');
log(`getElementsByClassName 类型: ${byClassName.constructor.name}`); // HTMLCollection
log(`querySelectorAll 类型: ${byQueryAll.constructor.name}\n`); // NodeList
// 实时性测试
log('=== 实时性测试 ===');
log('初始长度:');
log(`byClassName: ${byClassName.length} 个元素`);
log(`byQueryAll: ${byQueryAll.length} 个元素`);
// 添加新元素后再次检查
log('\n添加新元素后检查长度:');
// const newEl = document.createElement('div');
// newEl.className = 'sample-element';
// newEl.textContent = '动态添加的元素';
// document.body.appendChild(newEl);
log(`byClassName (实时更新): ${byClassName.length} 个元素`);
log(`byQueryAll (静态快照): ${byQueryAll.length} 个元素\n`);
// 方法支持对比
log('=== 方法支持对比 ===');
log('尝试使用forEach:');
log('byClassName.forEach: ' + (byClassName.forEach ? '支持' : '不支持'));
log('byQueryAll.forEach: ' + (byQueryAll.forEach ? '支持' : '支持') + '\n');
// 包含关系对比
log('=== 包含关系对比 ===');
constspecialElement = document.querySelector('.special');
log(`byClassName包含special元素: ${Array.from(byClassName).includes(specialElement)}`);
log(`byQueryAll包含special元素: ${Array.from(byQueryAll).includes(specialElement)}`);
}
functionaddNewElement() {
constnewEl = document.createElement('div');
newEl.className = 'sample-element';
newEl.textContent = `动态元素 ${document.getElementsByClassName('sample-element').length + 1}`;
document.body.appendChild(newEl);
}
functionaddStyle() {
byClassName[0].style['background-color'] = 'red';
console.log(byClassName[0].style, byQueryAll[0].style)
console.log(byClassName[0].style['background-color'], byQueryAll[0].style['background-color'])
}
</script>
</body>
</html>
运行截图案例1:原先有三个special类,新增一个special类后:


运行截图案例2:改变颜色,两个列表的对应属性都可以反映出来,所以这两个对象的属性是响应式变化的,实时更新的

(一)一个为动态集合,一个是静态列表,只体现在长度方面
document.getElementsByClassName获取的是HTMLCollection,是动态集合,document.querySelectorAll获取的NodeList,是静态列表。
也就是说原本长度是3,往页面再加了一个元素,那么HTMLCollection的长度更新为4,而NodeList的长度还是3。
(二)样式及属性方面
当操作了dom的样式或者dom的属性,HTMLCollection和NodeList的属性都会得到变化
(三)总结
总结:1.HTMLCollection可以实时知道元素长度的变化,NodeList无法知道知道元素长度的变化;2.两个集合中的元素属性都会实时更新,比如元素的属性或者内联样式发生变化时,都可以直接在相应的对象里面反应出来。
穷则独善其身,达则兼济天下……

浙公网安备 33010602011771号