【JavaScript】操作 DOM 节点


DOM 操作



节点的操作

获取节点

  1. parentNode:父节点(最高的父节点为 document)
  2. childNodes:所有子节点,返回类数组
  3. firstChild:第一个子节点
  4. lastChild:最后一个子节点
  5. nextSibling:下一个兄弟节点
  6. previousSibling:上一个兄弟节点
  • 兼容所有浏览器
<ul id="box">
    <li id="con1"></li>
    <li id="con2"></li>
    <li id="con3"></li>
</ul>
<script>
    console.log(box.parentNode); // <body> ... <//body>
    console.log(box.childNodes); // NodeList(7) [text, li#con1, text, li#con2, text, li#con3, text]
    console.log(box.firstChild); // #text
    console.log(box.lastChild); // #text
    console.log(box.nextSibling); // #text
    console.log(box.previousSibling); // #text
</script>
  • text:为文本节点,这里表示空格、换行

获取元素节点

  1. parentElement:父元素节点
  2. children:子元素节点,返回类数组
  3. firstElementChild:第一个子元素节点
  4. lastElementChild:最后一个子元素节点
  5. nextElementSibling:下一个兄弟元素节点
  6. previousElementSibling:上一个兄弟元素节点
  • 除了 children,IE8 及以下都不兼容
<ul id="box">
    <li id="con1"></li>
    <li id="con2"></li>
    <li id="con3"></li>
</ul>
<script>
    console.log(box.parentElement); // <body> ... <//body>
    console.log(box.children); // HTMLCollection(3) [li#con1, li#con2, li#con3]
    console.log(box.firstElementChild); // <li id="con1"></li>
    console.log(box.lastElementChild); // <li id="con3"></li>
    console.log(box.nextElementSibling); // <script> ... <//script>
    console.log(box.previousElementSibling); // null
</script>
  • 获取的都是元素节点,所以没有文本节点

创建节点

  1. document.createElement():创建元素节点
  2. document.createTextNode():创建文本节点
  3. document.createComment():创建注释节点
  4. document.createDocumentFragment():创建文档片段
let eleNode = document.createElement('span');
console.log(eleNode); // <span></span>

let textNode = document.createTextNode('文本内容');
console.log(textNode); // "文本内容"

let comNode = document.createComment('注释内容');
console.log(comNode); // <!-- 注释内容 -->

let fraNode = document.createDocumentFragment();
console.log(fraNode); // #document_fragment
  • 创建的节点不在 DOM 树上,所以不会被绘制到页面上

插入节点

  1. parentNode.appendChild(child):在 parentNode 的最后添加节点 child
  2. parentNode.insertBefore(frontChild, rearChild):把 frontChild 添加到 rearChild 前面
  • 把创建的节点插入到页面上的节点内,就可以在页面上显示啦
eg:最新评论,将节点插到最前面:
<ul id="box">
    <li id="con1"></li>
    <li id="con2"></li>
    <li id="con3"></li>
</ul>
<script>
    let eleNode = document.createElement('li');
    let textNode = document.createTextNode('文本');
    eleNode.appendChild(textNode);
    if (box.firstElementChild) { // 作为第一个节点
        box.insertBefore(eleNode, box.firstChild);
    } else {
        box.appendChild(eleNode);
    }
</script>

页面显示:

<ul id="box">
    <li>文本</li>
	<li id="con1"></li>
    <li id="con2"></li>
    <li id="con3"></li>
</ul>

**注意:**每一个节点都是唯一的,如果我们插入的节点是已经存在的节点,会删除之前的节点

删除节点

  1. parent.removeChild(child):删除节点 child,会返回被删除的节点
  2. element.remove():删除节点 element,没有返回值
<ul id="box">
    <li id="con1"></li>
    <li id="con2"></li>
    <li id="con3"></li>
</ul>
<script>
    box.removeChild(con2);
</script>

页面显示:

<ul id="box">
    <li id="con1"></li>
    <li id="con3"></li>
</ul>

替换节点

  1. parentNode.replace(newEle, oldEle):用节点 newEle 代替节点 oldEle,会返回被替换的节点
<ul id="box">
    <li id="con1"></li>
    <li id="con2"></li>
    <li id="con3"></li>
</ul>
<script>
    let liNode = document.createElement('li');
    liNode.className = 'new';
    box.replaceChild(liNode, con2);
</script>

页面显示:

<ul id="box">
    <li id="con1"></li>
	<li class="new"></li>
    <li id="con3"></li>
</ul>

如果用 con1 替换 con2,相当于删除 con2

其他

  1. element.hasChildNodes():用于判断一个元素节点有没有子节点,有则返回 true,无则返回 false
<ul id="box">
    <li id="con1"></li>
    <li id="con2"></li>
    <li id="con3"></li>
</ul>
<script>
    let result = box.hasChildNodes();
    console.log(result); // true
    result = con1.hasChildNodes();
    console.log(result); // false
</script>



元素节点

常用属性

  1. innerHTML:获取元素节点的内容,可读可写;如果内容符合 HTML 格式,会被解析成标签
  2. innerTEXT:获取元素节点的内容,可读可写;即使内容符合 HTML 格式,也不会被解析成标签
<div id="wrap1">123</div>
<div id="wrap2">123</div>
<script>
    wrap1.innerHTML = '<h4>文本</h4>';
    wrap2.innerText = '<h4>文本</h4>';
</script>

如果 wrap 内没有内容,则添加;有内容,则替换

获取内容时,innerHTML 是获取里面的标签内容;innerText 是获取里面的文本内容
<ul id="wrap">
    <li>香蕉</li>
</ul>
<script>
    console.log(wrap.innerHTML) // <li>香蕉</li>
    console.log(wrap.innerText) // 香蕉
</script>
我们可以利用该属性,减少页面重构和重绘的次数

方法 1:重构了 arr.length

<ul id="wrap"></ul>
<script>
    let arr = ['苹果', '雪梨', '香蕉'];
    let oLi;
    for (let index = 0; index < arr.length; index++) {
        oLi = document.createElement('li');
        oLi.innerText = arr[index]; // 使用 innerText 就无需创建文本节点了
        wrap.appendChild(oLi);
    }
</script>

方法 2:使用字符串拼接,重构了 1

<ul id="wrap"></ul>
<script>
    let arr = ['苹果', '雪梨', '香蕉'];
    let oLi = '';
    for (let index = 0; index < arr.length; index++) {
        oLi += '<li>' + arr[index] + '</li>';
    }
    wrap.innerHTML = oLi;
</script>

方法 3:使用文档片段,重构了 1

<div id="wrap"></div>
<script>
    let arr = ['苹果', '雪梨', '香蕉'];
    let oLi, oFrag;
    oFrag = document.createDocumentFragment();
    for (let index = 0; index < arr.length; index++) {
        oLi = document.createElement('li');
        oLi.innerText = arr[index];
        oFrag.appendChild(oLi); // 先存储在文档片段节点中
    }
    wrap.appendChild(oFrag); // 将文档片段节点添加到 wrap 中
</script>

控制属性的方法

  1. element.attributes.class / element.attributes['class']:获取元素节点的 class 属性(键值对)
    • element.attributes.class.name
    • element.attributes.class.value 等效于 element.className
  2. element.getAttribute('class') 等效于 element.attributes.class.value
  3. element.setAttribute('class', 'on'):设置元素节点的 class 属性值
  4. element.removeAttribute('class'):删除元素节点的 class 属性

上面的 class 可以换为其他属性名


获取 / 设置属性

1 方法

我们可以通过方法获取并修改元素的属性

  1. element.getAttribute('属性名')
  2. element.setAttribute('属性名', '属性值')

2 点语法

我们可以通过 . 获取并修改元素的属性

oImg.src = "images/2.jpg"; // 修改图片地址
oLianjie.href = "http://www.163.com"; // 修改超链接地址
oBox.value = "嘻嘻嘻嘻嘻"; // 修改表单的内容
oBox.style.color = 'red'; // 修改行内 CSS 样式

注意class 属性需要通过 className 获取,因为 class 是保留字

oDiv.className = "da"; // 修改类名,会覆盖原来的类名
oBox.className += ' hide'; // 添加类名,注意前面要有空格

区别

. 无法获取并修改自定义的属性;setAttribute() / getAttribute() 可以
<div id='box'></div>
let oBox = document.getElementById('box');
oBox.wu = 'super'; // 无效
oBox.setAttribute("su", "name");
console.log(oBox); // <div id='box' su='name'></div>

注意. 的效率比较高,所以一般都使用 . 操作

. 获取的属性是一个对象。我们可以再通过 . 获取子属性,eg:.style.color
getAttribute() 得到的是字符串
console.log(typeof oBox.style); // object
console.log(typeof oBox.getAttribute("style")); // string
getAttribute() 不需要避讳,比较直观
oBox.getAttribute('class')
oBox.className

. 获取的属性名要符合标识符规范。所以有连字符的属性名要写成小驼峰式

oBox.getAttribute('background-color')
oBox.style.backgroundColor



classList 属性

classList 是 H5 新增的属性,是一个类数组( IE9 及以下不兼容 )

用于设置元素节点的类名,有几个常用的方法:

  1. add('value'):添加类名 value,不会重复添加
  2. remove('value'):删除类名 value
  3. contains('value'):查询类名 value,返回布尔值
  4. toggle('value'):查询类名 value。有则删除,并返回 false;无则添加,并返回 true
  5. replace('old', 'new'):用 new 替换类名 old


自定义属性

H5 新增了自定义属性,需要以 data- 开头( IE10 及以下不兼容 )

元素节点有一个 dataset 属性用来获取和设置自定义属性

<div id="box" data-myName="man"></div>
let div = document.getElementById('box');

// 获取自定义属性值
console.log(div.dataset); // DOMStringMap {myname: "man"}

// 修改自定义属性值
div.dataset.myname = 'super'; // 属性名都是小写,不需要驼峰
// div.dataset['myname'] = 'super' // 两语句等效

console.log(div.dataset); // DOMStringMap {myname: "super"}
console.log(div); // <div id="box" data-myname="super"></div>
这里的 myname 必须都使用小写,myName 会在 HTML 中变成 data-my-name
let div = document.getElementById('box');

// 获取自定义属性值
console.log(div.dataset); // DOMStringMap {myname: "man"}

// 修改自定义属性值
div.dataset.myName = 'super'; // 属性名都是小写,不需要驼峰
// div.dataset['myName'] = 'super' // 两语句等效

console.log(div.dataset); // DOMStringMap {myname: "man", myName: "super"}
console.log(div); // <div id="box" data-myname="man" data-my-name="super"></div>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JS.Huang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值