DOM—操作元素(H5自定义属性) 节点操作(子、父、兄弟节点, 创建、添加节点, 删除节点,复制节点)

本文介绍了HTML5自定义属性的设置及其兼容性获取方法,强调了学习节点操作的原因和优势。详细讲解了节点的类型、层级关系,包括父节点、子节点、兄弟节点的获取与操作。同时,阐述了动态创建、添加、删除和复制节点的方法,以及解决兼容性问题的策略。最后,总结了DOM操作的主要内容,包括创建、增加、删除、修改和查询元素。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. H5自定义属性

目的:用于保存并使用数据。有些数据可以保存到页面中而不用保存到数据库中。

由于有些自定义属性很容易引起歧义,难以判断是元素内置属性还是自定义属性。

H5给我们新增了自定义属性:

1.1 设置H5自定义属性

H5规定自定义属性 date-开头作为属性名并且赋值

如:

 <div date-index = "1" ></div>
  1. 兼容性获取 element.getAttribute('data-index')
  2. H5新增方法 element.dataset.indexelement.dataset['index'] 获取。(ie11或以上才能使用)
  3. 如果自定义属性里面有多个链接的单词,则使用驼峰命名法获取。

Warning

对于 element.dataset.index element.dataset['index'] 方法,注意 indexdata-index 中的要对应。

<body>
    <div getTime="20" data-index="2" data-list-name="lili"></div>
    <script>
        var div = document.querySelector('div');
        console.log(div.getTime);  //undefine
        console.log(div.getAttribute('getTime'));  //20
        console.log(div.getAttribute('data-list-name'));  //这种方法直接这样写
        div.setAttribute('data-time', 20);
        // H5新增的获取自定义属性的方法
        // dataset是一个集合,里面存放了所有以data开头的自定义属性
        console.log(div.dataset);   //有两个 2和20
        console.log(div.dataset.index);  //2  (取其中的index)
        // 如果自定义属性里有多个单词,新增方法用驼峰法获取
        console.log(div.dataset.listName);  //lili  
        console.log(div.dataset['listName']);  //lili  也可以这样表示

    </script>
</body>

2. 节点操作

2.1 为什么学习节点操作

获取元素通常使用两种方式:

  1. 利用DOM提供的方法获取元素,缺点:逻辑性不强、繁琐

    • document.getElementByld()
    • document.getElementsByTagName()
    • document.querySelector()
  2. 利用 节点层级关系 获取元素

    • 利用父子兄节点关系获取元素
    • 优点:逻辑性强
    • 缺点:兼容性稍差

两种方式都可以获取节点,但节点操作更简单

2.2 节点概述

网页中的所有内容都是节点(标签、属性、文本、注释等),在DOM中,节点使用 node 来表示。

HTML DOM 树中的所有节点均可通过 JavaScript 进行访问,所有 HTML 元素(节点)均可被修改,也可以创建或删除。

一般地,节点至少拥有 nodeType (节点类型)、nodeName (节点名称) nodeValue (节点值)这三个基本属性。

三种基本节点类型:

  • 元素节点 nodeType 1
  • 属性节点 nodeType 2
  • 文本节点 nodeType 3(文字、空格、换行)

实际开发中,主要操作的还是元素节点

2.3 节点层级

2.3.1 父级节点

获取离元素最近的父节点,若找不到则返回 null

node.parentNode
<body>
    <div class="box">
        <div class="erweima">x</div>
    </div>
    <script>
        // 1. 父节点 parentNode
        var erweima = document.querySelector('.erweima');
        // var box =document.querySelector('.box');  //之前的方法要这样获取父元素
        // 得到的是离元素最近的父级节点  如果找不到父节点就返回为null
        console.log(erweima.parentNode);
    </script>
</body>

2.3.2  子级节点

parentNode.childNodes

parentNode.childNodes 返回包含指定 节点的子节点的集合,该集合为即时更新的集合。

注意parentNode.childNodes 包含了所有的子节点,包括元素节点,文本节点等。 如果只想要获得里面的元素节点,则需要专门处理。所以我们一般不提倡使用 childNodes

// 筛选元素节点
        var ul = document.querySelector('ul');
        for (var i = 0; i < ul.childNodes.length; i++) {
            if (ul.childNodes[i].nodeType === 1) {
                // ul.childNodes[i]是元素节点
                console.log(ul.childNodes[i]);
            }
        }

更加好的方法:获取子元素节点

parentNode.children;  (非标准)

 parentNode.children是一个只读属性,返回所有的子元素节点。它只返回子元素节点,其余节点不返回(重点掌握

<body>
    <ul>
        <li>我是li</li>
        <li>我是li</li>
        <li>我是li</li>
        <li>我是li</li>
    </ul>
    <script>
        // 2. 子节点 
        // (1)childNodes 获取所有的子节点 包含 元素节点 文本节点等
        // DOM提供的方法(API)获取
        var ul = document.querySelector('ul');
        var lis = document.querySelectorAll('li');
        // 节点法获取
        console.log(ul.childNodes);  //[text, li, text, li, text, li, text, li, text]
        console.log(ul.childNodes[0].nodeType);  //3  索引号0是text 文本节点 为3
        console.log(ul.childNodes[1].nodeType);  //1  索引号0是li 元素节点 为1
        // (2)children获取所有的子元素节点  实际开发中常用
        console.log(ul.children);  //[li, li, li, li]
    </script>
</body>

子节点方法:

① 获取 所有结点 中的第一个和最后一个:

  • parentNode.firstChild
  • parentNode.lastChild

② 获取 元素节点中第一个和最后一个

  • parentNode.firstElementChild
  • parentNode.lastElementChild

(IE9或以上浏览器可用)

实际开发

  • parentNode.children[0]
  • parentNode.children[parentNode.children.length -1]
<body>
    <ol>
        <li>我是li1</li>
        <li>我是li2</li>
        <li>我是li3</li>
        <li>我是li4</li>
    </ol>
    <script>
        var ol = document.querySelector('ol');
        // 1. firstChild 第一个子节点(包括元素节点、属性节点、文本节点)(lastChild一样)
        console.log(ol.firstChild);  //返回的是text
        console.log(ol.lastChild);  //返回的是text
        // 2. firstElementChild 第一个字元素节点(只包括元素节点)
        console.log(ol.firstElementChild);  //返回的是第一个li
        console.log(ol.lastElementChild);  //返回的是最后一个li
        // 3. 实际开发的写法,既没有兼容性问题又返回第一个子元素
        console.log(ol.children[0]);  //第一个li
        console.log(ol.children[ol.children.length - 1]);//最后一个li
    </script>
</body>

2.3.3 兄弟节点

  1. 返回下一个兄弟节点:

    node.nextSibling
  2. 返回上一个的兄弟节点:

    node.previousSibling

    nextsibling / previousSibling 返回当前元素的下/上一个兄弟节点,找不到则返回 null。这个兄弟节点可能是是所有的节点之一(即元素节点、文本节点等)。

  3. 返回下一个 兄弟元素节点(≥IE9)

    node.nextElementSibling
  4. 返回上一个 兄弟元素节点(≥IE9)

    node.previousElementSibling

    nextElementSibling / previousElementSibling 返回当前元素下/上一个兄弟元素节点,找不到则返回 null

注意:这两个方法(nextElementSibling / previousElementSibling)有兼容性问题,IE9 以上才支持。

<body>
    <p></p>
    <div>我是div</div>
    <span>我是span</span>
    <script>
        // 3. 兄弟节点 
        var div = document.querySelector('div');
        // nextSibling 下一个兄弟节点,包含 元素节点 文本节点等
        console.log(div.nextSibling);  //text
        // nextElementSibling 下一个兄弟元素节点
        console.log(div.nextElementSibling);  //得到的是span
        // previousSibling 上一个兄弟节点,包含 元素节点 文本节点等
        console.log(div.previousSibling);  //text
        // previousElementSibling 上一个兄弟元素节点
        console.log(div.previousElementSibling);  //得到的是p
    </script>
</body>

      5. 如何解决兼容性问题:封装一个函数

// 处理 <IE9 兼容性问题
function getNextElementSibling(element) {
    var el = element;
    while (el = el .nextSibling) {
        if (el .nodeType === 1) {
            return el ;
        }
    }
    return null;
}

2.4 创建并添加节点

document.createElement("tagName");

document.createElement() 方法创建由 tagName 指定的 HTML 元素。因为这些元素原先不存在,是根据我们的需求动态生成的,所以我们也称为 动态创建元素节点

在创建了元素节点后,还需要将节点添加到页面中。appendChild() 方法可以给元素节点添加子元素节点,若某元素已存在则重复添加,在页面已存在的元素 后面追加新节点。(无需引号)

 parentNode.appendChild(chileNode)

类似的,也可以使用 insertBefore() 方法在指定元素的前面插入节点。(无需引号)

let insertedNode = parentNode.insertBefore(newNode, referenceNode)
<body>
    <ul>
        <li>lili</li>
    </ul>
    <script>
        // 1. 创建元素节点
        var li = document.createElement('li');
        // 2. 添加节点  node.appendChild(child)  node 父级  child 子级  后面追加元素,类似于数组中的push
        var ul = document.querySelector('ul');
        ul.appendChild(li);  //后面添加
        // 3. 添加节点 node.insertBefore(child,指定元素)
        var lili = document.createElement('li');
        ul.insertBefore(lili, ul.children[0]); //前面添加
    </script>
</body>

参数说明:

  • insertedNode:同 newNode,待插入的新节点。
  • parentNode:被插入的父节点。
  • newNode:待插入的新节点。
  • referenceNode:指定元素节点,新节点将插入到该元素节点的前面。

Tip.   在一个页面中要添加元素节点,先创建节点,然后添加节点

2.5 删除节点

DOM 提供了 removeChild(childNode) 方法,删除一个子节点,并返回删除的节点。其中 childNode 为待删除的子节点。

// 方式一
parentNode.removeChild(childNode);
// 方式二
let oldChild = parentNode.removeChild(childNode);
<body>
    <button>删除</button>
    <ul>
        <li>熊大</li>
        <li>熊二</li>
        <li>光头强</li>
    </ul>
    <script>
        // 1. 获取元素
        var ul = document.querySelector('ul');
        var btn = document.querySelector('button');
        // 2. 注册事件

        // 点击按钮 依次删除里面的孩子
        btn.onclick = function () {
            if (ul.children.length == 0) {
                this.disabled = true;
            } else {
                ul.removeChild(ul.children[0]);
            }

        }
    </script>
</body>

2.6 复制节点 

node.cloneNode() 方法返回调用该方法的节点的一个副本。也称为克隆节点/拷贝节点。其中 node 为被克隆的元素节点。

node.cloneNode([deep]);

或者

let newClone = node.cloneNode([deep]);

对于 deep 参数,可以为 true false或为空的

deep 参数值含义
true深拷贝,同时复制节点本身和里面的子节点
false浅拷贝,只复制节点本身,不复制子节点
空,同 false
<body>
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
    <script>
        var ul = document.querySelector('ul');
        // var lili = ul.children[0].cloneNode();//在最后面只生成一个点 . 不生成文字(浅拷贝)
        var lili = ul.children[0].cloneNode([true]);//在最后面生成了 . 1(深拷贝)
        ul.appendChild(lili);

    </script>
</body>

2.7 三种动态创建元素的区别

  • document.write()
  • element.innerHTML
  • element.createElement()

区别:

  1. document.write() 创建元素,是直接将内容写入页面的内容流,但是 当文档流执行完毕,会导致页面全部重绘。即覆盖原本的页面。
  2. innerHTML 是将内容写入某个 DOM 节点,不会导致页面全部重绘。
  3. innerHTML 创建多个元素效率更高(不要拼接字符串,采取数组形式拼接),结构稍微复杂。
  4. createElement() 创建多个元素效率稍低一点点,但是结构更清晰。

总结:不同浏览器下,innerHTML 效率要比 creatElement高。

<body>
    <button>点击</button>
    <p>abc</p>
    <div class="inner"></div>
    <div class="create"></div>
    <script>
        // window.onload = function() {
        //         document.write('<div>123</div>');

        //     }
        // 三种创建元素方式区别 
        // 1. document.write() 创建元素  如果页面文档流加载完毕,再调用这句话会导致页面重绘
        // var btn = document.querySelector('button');
        // btn.onclick = function() {
        //     document.write('<div>123</div>');
        // }

        // 2. innerHTML 创建元素
        var inner = document.querySelector('.inner');
        // for (var i = 0; i <= 100; i++) {
        //     inner.innerHTML += '<a href="#">百度</a>'
        // }
        var arr = [];
        for (var i = 0; i <= 100; i++) {
            arr.push('<a href="#">百度</a>');
        }
        inner.innerHTML = arr.join('');
        // 3. document.createElement() 创建元素
        var create = document.querySelector('.create');
        for (var i = 0; i <= 100; i++) {
            var a = document.createElement('a');
            create.appendChild(a);
        }
    </script>
</body>

3. DOM 学习总结 

关于 dom 操作,我们主要针对于元素的操作。主要有创(建)、增、删、改、查、属性操作、事件操作。

3.1 创

  • document.write
  • innerHTML
  • createElement

3.2 增

  • appendChild
  • insertBefore

3.3 删

  • removeChild

3.4 改 

主要修改 dom 的元素属性,dom 元素的内容、属性,表单的值等。

  • 修改元素属性:srchreftitle
  • 修改普通元素内容:innerHTMLinnerText
  • 修改表单元素:valuetypedisabled
  • 修改元素样式:styleclassName

3.5 查

主要获取查询dom的元素

  • DOM提供的API 方法:getElementByIdgetElementsByTagName古老用法不太推荐
  • H5提供的新方法:querySelectorquerySelectorAll 提倡
  • 利用节点操作获取元素:父(parentNode)、子(children)、兄(previousElementSiblingnextElementSibling)提倡

6.6 属性操作 

主要针对于自定义属性

  • setAttribute:设置dom的属性值
  • getAttribute:得到dom的属性值
  • removeAttribute:移除属性

6.7  事件操作

给元素注册事件,格式:事件源.事件类型 = 事件处理程序

鼠标事件触发条件
onclick鼠标点击左键触发
onmouseover鼠标经过触发
onmouseout鼠标离开触发
onfocus获得鼠标焦点触发
onblur失去鼠标焦点触发
onmousemove鼠标移动触发
onmouseup鼠标弹起触发
onmousedown鼠标按下触发
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值