深入理解DOM节点操作
前面的话
一般地,提起操作会想到“增删改查”这四个字,而DOM节点操作也类似地对应于此,接下来将详细介绍DOM的节点操作方法
前提
DOM提供节点操作的方法是因为DOM节点关系指针都是只读的
下列代码中想通过修改myUl的父级节点来修改其节点关系,但由于parentNode属性是只读的,所以修改无效,在IE8-浏览器下甚至会报错
<div id="myDiv"></div>
<ul id="myUl">
<li id="myli"></li>
</ul>
<script>
console.log(myUl.parentNode);//<body>
myUl.parentNode = myDiv;
//标准浏览器下,依然返回<body>;而IE8-浏览器则会报错
console.log(myUl.parentNode);
</script>
DOM节点操作方法包括创建节点、插入节点、删除节点、替换节点、查看节点和复制节点。查看节点指的是查看节点之间的关系,在节点关系部分已经做过详细介绍,就不再赘述
创建节点
createElement()
document.createElement()方法可以创建新元素。这个方法接受一个参数,即要创建元素的标签名,这个标签名在HTML文档中不区分大小写
var oDiv = document.createElement("div");
console.log(oDiv);//<div>
IE8-浏览器可以为这个方法传入完整的元素标签,也可以包含属性
var oDiv = document.createElement('<div id="box"></div>');
console.log(oDiv.id);//'box'
利用这种方法可以避开IE7-浏览器在动态创建元素的下列问题
1、不能设置动态创建的<iframe>元素的name特性
2、不能通过表单的reset()方法重设动态创建的<input>元素
3、动态创建的type特性值为"reset"的<button>元素重设不了表单
4、动态创建的一批name相同的单选按钮彼此毫无关系。name值相同的一组单选按钮本来应该用于表示同一选项的不同值,但动态创建的一批这种单选按钮之间却没有这种关系
var iframe = document.createElement("<iframe name = 'myframe'></iframe>");
var input = document.createElement("<input type='checkbox'>);
var button = document.createElement("<button type = 'reset'></button>");
var radio1 = document.createElement("<input type='radio' name ='choice' value = '1'>");
var radio2 = document.createElement("<input type='radio' name ='choice' value = '2'>");
所有节点都有一个ownerDocument的属性,指向表示整个文档的文档节点document;在使用createElement()方法创建新元素的同时,也为新元素设置了ownerDocument属性
<div id="myDiv"></div>
<script>
console.log(myDiv.ownerDocument);//document
var newDiv = document.createElement('div');
console.log(newDiv.ownerDocument);//document
console.log(newDiv.ownerDocument === myDiv.ownerDocument);//true
</script>
插入节点
appendChild()
appendChild()方法用于向childNodes列表的末尾添加一个节点,并返回新增节点。添加节点后,childNodes中的新增节点、父节点和以前的最后一个子节点的关系指针都会相应地得到更新
<div id="box"></div>
<script>
var oBox = document.getElementById('box');
var newNode = document.createElement('ul');
var returnedNode = oBox.appendChild(newNode);
console.log(returnedNode.nodeName);//UL
console.log(returnedNode == newNode);//true
console.log(returnedNode == oBox.lastChild);//true
</script>
如果插入的节点已经是文档的一部分了,那结果就是将该节点从原来的位置转移到新位置
<body>
<div id="oldDiv">第一个div</div>
<div id="newDiv">第二个div</div>
<button id="btn">变换位置</button>
<script>
btn.onclick = function(){
document.body.appendChild(newDiv);
}
</script>
</body>
insertBefore()
insertBefore()方法接收两个参数:要插入的节点和作为参照的节点。插入节点后,被插入的节点会变成参照节点的前一个兄弟节点(previousSibling),同时被方法返回。如果参照节点是null,则insertBefore()与appendChild()方法执行相同的操作。同样地,如果插入的节点已经是文档的一部分了,那结果就是将该节点从原来的位置转移到新位置
referenceNode.parentNode.insertBefore(newNode,referenceNode);
<ul id="myUl" style="border:1px solid black;">
<li id="myLi">
<div id='oldDiv'>oldDiv</div>
</li>
</ul>
<button id="btn1">插入oldDiv的前面</button>
<button id="btn2">插入myUl的前面</button>
<button id="btn3">插到oldDiv的里面</button>
<script>
var oDiv = document.createElement('div');
oDiv.innerHTML = 'newDiv';
btn1.onclick = function(){
console.log(myLi.insertBefore(oDiv,oldDiv));//<div>newDiv</div>
}
btn2.onclick = function(){
console.log(document.body.insertBefore(oDiv,myUl));//<div>newDiv</div>
}
btn3.onclick = function(){
console.log(oldDiv.insertBefore(oDiv,null));//<div>newDiv</div>
}
</script>
【小效果】
<ul class="list" id="list">
<li class="in">1</li>
<li class="in">2</li>
<li class="in">3</li>
<li class="in">4</li>
<li class="in">5</li>
<li class="in">6</li>
</ul>
<script>
var oList = document.getElementById('list');
//新增一个li元素
var oAdd = document.createElement('li');
//设置新增元素的css样式
oAdd.className = "in";
oAdd.style.cssText = 'background-color:red;border-radius:50%';
//添加到oList中
oList.insertBefore(oAdd,null);
var num = -1;
var max = oList.children.length;
function incrementNumber(){
num++;
//oList.getElementsByTagName('li')[max]相当于null,所以不报错
oList.insertBefore(oAdd,oList.getElementsByTagName('li')[num]);
if(num == max){
num = -1;
}
if(num == 0){
num = 1;
}
setTimeout(incrementNumber,1000);
}
setTimeout(incrementNumber,1000);
</script>
insertAfter()
由于不存在insertAfter()方法,如果要插在当前节点的某个子节点后面,可以用insertBefore()和appendChild()封装方法
function insertAfter(newElement,targetElement){
var parent = targetElement.parentNode;
if(parent.lastChild == targetElement){
parent.appendChild(newElement);
}else{
parent.insertBefore(newElement,targetElement.nextSibling)
}
}
<div id='oldDiv'>old</div>
<button id="btn">增加节点</button>
<script>
function insertAfter(newElement,targetElement){
var parent = targetElement.parentNode;
if(parent.lastChild == targetElement){
return parent.appendChild(newElement);
}else{
return parent.insertBefore(newElement,targetElement.nextSibling)
}
}
var newDiv = document.createElement('div');
newDiv.innerHTML = 'new';
btn.onclick = function(){
insertAfter(newDiv,oldDiv);
}
</script>
insertAdjacentHTML()
insertAdjacentHTML()方法作为终级办法,相当于前面三个方法的综合。该方法接收两个参数:插入的位置和要插入的HTML文本
第一个参数必须是下列值之一,且这些值都必须是小写形式:
"beforebegin" 在当前元素之前插入一个紧邻的同级元素
"afterbegin" 在当前元素之下插入一个新的子元素或在第一个子元素之前再插入新的子元素
"beforeend" 在当前元素之下插入一个新的子元素或在最后一个子元素之后再插入新的子元素
"afterend" 在当前元素之后插入一个紧邻的同级元素
第二个参数是一个HTML字符串,如果浏览器无法解析字符串,就会抛出错误
[注意]该方法无返回值
<div id='target' style="border: 1px solid black;">This is the element content</div>
<button>beforebegin</button>
<button>afterbegin</button>
<button>beforeend</button>
<button>afterend</button>
<script>
var btns = document.getElementsByTagName('button');
for(var i = 0 ; i < 4; i++){
btns[i].onclick = function(){
var that = this;
target.insertAdjacentHTML(that.innerHTML,'<span id="test">测试</span>')
}
}
</script>
移除节点
removeChild()
removeChild()方法接收一个参数,即要移除的节点,被移除的节点成为方法的返回值
<div id="myDiv">等待移除的节点</div>
<button id="btn">移除节点</button>
<script>
btn.onclick = function(){
document.body.removeChild(myDiv);
}
</script>
下面代码可以移除当前节点的所有子节点
var element = document.getElementById("top");
while (element.firstChild) {
element.removeChild(element.firstChild);
}
【小效果】
<button id="btn">开始删除节点</button>
<ul class="list" id="list">
<li class="in">1</li>
<li class="in">2</li>
<li class="in">3</li>
<li class="in">4</li>
<li class="in">5</li>
<li class="in">6</li>
</ul>
<script>
var oList = document.getElementById('list');
function incrementNumber(){
//获取oList中子元素的个数
var len = oList.getElementsByTagName('li').length;
//如果长度不为0
if(len){
//删除最后一个子元素
oList.removeChild(oList.getElementsByTagName('li')[len-1]);
//再次调用计时器
setTimeout(incrementNumber,1000);
}
}
btn.onclick = function(){
//1s后执行函数incrementNumber
setTimeout(incrementNumber,1000);
}
</script>
remove()
相比于removeChild(),remove()方法不太常见,但是却非常简单。该方法不用调用其父节点,直接在当前节点使用remove()方法就可以删除该节点,无返回值
remove()方法常用于删除元素节点和文本节点,不可用于特性节点
[注意]IE浏览器不支持该方法
<div id="test" title='div'>123</div>
<script>
//文本节点
console.log(test.childNodes[0]);//'123'
test.childNodes[0].remove();
console.log(test.childNodes[0]);//undefined //特性节点
console.log(test.attributes.title);//'div'
//报错,remove()方法无法用于删除特性节点
try{test.attributes[0].remove()}catch(e){
console.log('error');
}
//元素节点
console.log(test);
test.remove();
</script>
替换节点
replaceChild()
replaceChild()接收的两个参数是要插入的节点和要替换的节点,要替换的节点将由这个方法返回并从文档树中移除,同时由要插入的节点占据其位置
oldChild.parentNode.replaceChild(newChild, oldChild);
<div id="div1">1</div>
<div id="div2">2</div>
<div id="div3">3</div>
<button id="btn1">新增节点替换(4替换2)</button>
<button id="btn2">原有节点替换(3替换1)</button>
<script>
btn2.onclick = function(){
document.body.replaceChild(div3,div1);
}
btn1.onclick = function(){
var div4 = document.createElement('div');
div4.innerHTML = '4';
document.body.replaceChild(div4,div2);
}
</script>
【小效果】
<button id="btn">开始替换节点</button>
<ul class="list" id="list">
<li class="in">1</li>
<li class="in">2</li>
<li class="in">3</li>
<li class="in">4</li>
<li class="in">5</li>
<li class="in">6</li>
</ul>
<script>
var oList = document.getElementById('list');
//新增一个li元素
var oAdd = document.createElement('li');
//设置新增元素的css样式
oAdd.className = "in";
oAdd.style.cssText = 'background-color:red;border-radius:50%';
btn.onclick = function(){
//1s后oAdd替换第0个li
setTimeout(function(){
oList.replaceChild(oAdd,document.getElementsByTagName('li')[0]);
//1s后执行incrementNumber函数
setTimeout(incrementNumber,1000);
},1000);
} function incrementNumber(){
//获取oList中第1个li
var oLi1 = document.getElementsByTagName('li')[1];
//若存在则进行替换处理
if(oLi1){
oList.replaceChild(oAdd,oLi1);
setTimeout(incrementNumber,1000);
}
}
</script>
复制节点
cloneNode()
cloneNode方法用于克隆一个节点。它接受一个布尔值作为参数,表示是否执行深复制。在参数为true时,执行深复制,也就是复制节点及整个子节点树。在参数为false的情况下,执行浅复制,即复制节点本身。复制后返回的节点副本属于文档所有,但并没有为它指定父节点。若参数为空,也相当于false
[注意]cloneNode()方法不会复制添加到DOM节点中的javascript属性,例如事件处理程序等。这个方法只复制特性和子节点,其他一切都不会复制
<ul id="list">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
</ul>
<script>
var oList = document.getElementById('list');
oList.index = 0; var deepList = oList.cloneNode(true);
//成功复制了子节点
console.log(deepList.children.length);//
//但并没有复制属性
console.log(deepList.index);//undefined
var shallowList = oList.cloneNode();
//浅复制不复制子节点
console.log(shallowList.children.length);//
</script>
深入理解DOM节点操作的更多相关文章
- (转载)html dom节点操作(获取/修改/添加或删除)
DOM 是关于如何获取.修改.添加或删除 HTML 元素的标准,下面为大家介绍下html dom节点操作,感兴趣的朋友可以参考下 HTML DOM 是关于如何获取.修改.添加或删除 HTML 元素 ...
- 04-老马jQuery教程-DOM节点操作及位置和大小
1. jQuery创建DOM标签 1.1 DOM动态创建标签的方法 DOM时代我们通过document的createElement方法动态创建标签.创建标签后,动态的给他添加属性.例如代码: // 动 ...
- 第一百六十七节,jQuery,DOM 节点操作,DOM 节点模型操作
jQuery,DOM 节点操作,DOM 节点模型操作 学习要点: 1.创建节点 2.插入节点 3.包裹节点 4.节点操作 DOM 中有一个非常重要的功能,就是节点模型,也就是 DOM 中的“M”.页面 ...
- 前端JavaScript之DOM节点操作
1.HTML DOM是啥 Document Object Model:定义了访问和操作HTML文档的标准方法,把HTML文档呈现为带有元素,属性和文本的树状结构 2.解析过程 HTML加载完毕,渲染引 ...
- Dom节点操作总结
Dom 一:Dom的概念 Dom的简介: 全称为 document object model 文档对象模型,是操作文档的一整套方法 - 文档 - html,document时一个对象,是dom ...
- 深入理解DOM节点类型第五篇——元素节点Element
× 目录 [1]特征 [2]子节点 [3]特性操作[4]attributes 前面的话 元素节点Element非常常用,是DOM文档树的主要节点:元素节点是html标签元素的DOM化结果.元素节点主要 ...
- 深入理解DOM节点类型第四篇——文档片段节点DocumentFragment
× 目录 [1]特征 [2]作用 前面的话 在所有节点类型中,只有文档片段节点DocumentFragment在文档中没有对应的标记.DOM规定文档片段(document fragment)是一种“轻 ...
- 深入理解DOM节点类型第一篇——12种DOM节点类型概述
× 目录 [1]元素 [2]特性 [3]文本[4]CDATA[5]实体引用[6]实体名称[7]处理指令[8]注释[9]文档[10]文档类型[11]文档片段[12]DTD 前面的话 DOM是javasc ...
- 第6章 DOM节点操作
一.创建节点 为了使页面更加智能化,有时我们想动态的在 html 结构页面添加一个元素标签,那么 在插入之前首先要做的动作就是:创建节点. varbox=$('<div id="box ...
随机推荐
- 【.net 深呼吸】细说CodeDom(3):命名空间
在上一篇文章中,老周介绍了表达式和语句,尽管老周没有把所有的内容都讲一遍,但相信大伙至少已经掌握基本用法.在本文中,咱们继续探讨 CodeDom 方面的奥秘,这一次咱们聊聊命名空间. 在开始之前,老周 ...
- CentOS下mysql数据库常用命令总结
mysql数据库使用总结 本文主要记录一些mysql日常使用的命令,供以后查询. 1.更改root密码 mysqladmin -uroot password 'yourpassword' 2.远程登陆 ...
- VS15 preview 5打开文件夹自动生成slnx.VC.db SQLite库疑惑?求解答
用VS15 preview 5打开文件夹(详情查看博客http://www.cnblogs.com/zsy/p/5962242.html中配置),文件夹下多一个slnx.VC.db文件,如下图: 本文 ...
- 港真,到底应该选择OA还是BPM?
越来越多企业意识到流程管理的重要性,但是,选择OA还是BPM,却让他们产生了选择困难症. 一方面,企业皆注重流程的高效运转,最好内外部的业务都能用一个系统来解决.所有流程一天就能上线什么的,那就更好啦 ...
- Apache Cordova开发Android应用程序——番外篇
很多天之前就安装了visual studio community 2015,今天闲着么事想试一下Apache Cordova,用它来开发跨平台App.在这之前需要配置N多东西,这里找到了一篇MS官方文 ...
- 海鑫智圣:物联网漫谈之MQTT协议
什么是MQTT协议 MQTT(消息队列遥测传输协议)是IBM在1999年专门针对物联网等应用场景来制订的轻量级双向消息传输协议,它主要是为了解决物联网上使用到的设备的互相通信的问题,以及这些设备与后端 ...
- Ubuntu下开启php调试模式,显示报错信息
在Ubuntu下php的缺省设置是不显示错误信息的,如果程序出错会显示“无法处理此请求的错误提示”,这在开发环境下非常不方便. 其实我们只要编辑下apache的配置文件就好 1.我的apache 配置 ...
- liunx 磁盘管理命令记录
Linux磁盘管理好坏管理直接关系到整个系统的性能问题. Linux磁盘管理常用三个命令为df.du和fdisk. df:列出文件系统的整体磁盘使用量 du:检查磁盘空间使用量 fdisk:用于磁盘分 ...
- VPN连接常见错误汇总
提示远程服务器没有响应. 这种情况有两种情况,一种是远程服务器出现故障.另一种是自己的电脑出现问题,具体原因我还没有找到,但是可以肯定的是注册表除了问题,一个终极的解决办法就是把注册表替换了.先将HK ...
- linux常用查看硬件设备信息命令
转载:http://blog.chinaunix.net/uid-26782198-id-3242120.html # uname -a # 查看内核/操作系统/CPU信息 ...