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.两个集合中的元素属性都会实时更新,比如元素的属性或者内联样式发生变化时,都可以直接在相应的对象里面反应出来。
#
作者:兜里还剩五块出头
出处:https://www.cnblogs.com/hmy-666/p/18743800
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!