window.getComputedStyle方法 和 document.getElementsByClassName获取的样式有何不一样?document.getElementsByClassName和document.querySelectorAll返回的节点又有哪里不一样?

一、window.getComputedStyle方法 和 document.getElementsByClassName获取的样式有何不一样?#

(一)用途与功能差异#

  1. document.getElementsByClassName

    • 用途:用于通过类名获取元素集合(返回 HTMLCollection),不直接涉及样式操作 
    • 返回值:动态的 DOM 元素集合,仅包含符合条件的元素引用,需遍历元素后单独处理样式。
  2. window.getComputedStyle

    • 用途:获取单个元素的所有计算样式(包括行内样式、CSS 样式表、继承样式和浏览器默认样式),返回 CSSStyleDeclaration 对象 
    • 返回值:包含元素最终生效的样式属性和值的只读对象,支持通过属性名或 getPropertyValue() 访问具体样式值 

(二)样式来源与实时性#

  1. 样式来源

    • getElementsByClassName 间接获取的样式:
      需通过遍历元素后访问 element.style,但此方式仅能读取行内样式(如 <div style="color:red">),无法获取 CSS 样式表中定义的样式 
    • getComputedStyle 获取的样式:
      整合所有来源的样式,包括行内、CSS 样式表、继承和默认样式,返回最终应用的实时计算结果 
  2. 实时性方面

    • getElementsByClassName 返回的集合:
      是动态的,若 DOM 中新增/删除符合类名的元素,集合会自动更新 
    • getComputedStyle 返回的样式对象:
      是实时更新的,若元素样式发生改变(如通过 JavaScript 动态修改),再次访问会反映最新值 

(三)读写能力与兼容性#

    1. 读写能力

      • element.style(通过 getElementsByClassName 遍历后访问):
        • 可读可写,直接修改行内样式(如 element.style.color = 'red') 
        • 无法读取非行内样式,且可能因 CSS 优先级(如 !important)导致修改无效 
      • getComputedStyle
        • 只读,无法通过此方法修改样式,仅用于获取当前生效的样式值 
    2. 浏览器兼容性

      • 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.两个集合中的元素属性都会实时更新,比如元素的属性或者内联样式发生变化时,都可以直接在相应的对象里面反应出来。

 #

posted @   兜里还剩五块出头  阅读(2)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示
主题色彩