前言:这是笔者学习之后自己的理解与整理。如果有错误或者疑问的地方,请大家指正,我会持续更新!

节点关系

  DOM 可以将任何HTML描绘成一个由多层节点构成的结构。每个节点都拥有各自的特点、数据和方法,也与其他节点存在某种关系。节点之间的关系构成了层次,而所有页面标签则表现为一个以特定节点为根节点的树形结构,也就是 DOM 树。下图为各节点之间的关系:

  

父级属性

parentNode 和 parentElement

  每个节点都有一个 parentNode 属性,该属性指向文档树中的父节点。对于一个节点来说,它的父节点只可能是三种类型:document节点、element节点和documentfragment节点。如果不存在,则返回null;

  document 是一个文档对象,使用 document 对象可以对 HTML 文档进行检查、修改或添加内容,并处理该文档内部的事件。浏览器打开一个 HTML 文档时,该文档就成了一个 document 对象,Document 对象使我们可以对 HTML 页面中的所有元素进行访问。它是 window 对象的一部分,可用 window.document,往往省略 window。

  document 对象是文档的根节点,documentElement 属性是文档的根元素 html。

  document.childNodes 属性返回该对象的所有子节点;对 HTML 文档来说,document 对象一般有两个子节点;

  第一个子节点是 document.doctype,表示文档类型节点(DocumentType)。对 HTML5 文档来说,该对象就是 <!DOCTYPE html> ;

  第二个子节点是 document.documentElement,表示元素节点(Element)。也就是 <html>;

 

  与 parentNode 属性不同的是,parentElement 返回的是父元素节点;在IE浏览器中,只有 Element 元素节点才有该属性,其他浏览器则是所有类型的节点都有该属性;

  parentElement 匹配的是 parent 为 element 的情况,而 parentNode 匹配的则是 parent 为 node 的情况。element 是包含在 node 里的,它的 nodeType 是1。

  一般情况 parentNode 可以取代 parentElement 的所有功能。

        <div id="parent">
<div id="child"></div>
</div>
<script type="text/javascript">
var oParent = document.getElementById('parent');
var oChild = document.getElementById('child'); console.log(oChild.parentElement); //<div id="parent">...</div>
console.log(oChild.parentNode);//<div id="parent">...</div>
</script>

子级属性

childNodes 和 children

  childNodes 是一个只读的类数组对象,它保存着该节点的第一层子节点(包括空文本节点);

  children 是一个只读的类数组对象,但它保存的是该节点的第一层元素子节点(不包含空白文本节点);

childElementCount 和 children.length

  childElementCount 是返回子元素节点的个数;

  children.length 是返回子节点的长度;

其次,还有 firstChild 和 firstElementChild 的不同,lastChild 和 lastElementChild 的不同;

        <div id="parent">
<div id="child"></div>
</div>
<script type="text/javascript">
var oParent = document.getElementById('parent');
var oChild = document.getElementById('child'); console.log(oChild.parentElement); //<div id="parent">...</div>
console.log(oChild.parentNode);//<div id="parent">...</div> //childNodes 是一个只读的类数组对象,它保存着该节点的第一层子节点(包括空文本节点);
console.log(oParent.childNodes);//[text, div#child, text]
console.log(oParent.childNodes.length);//3
console.log(oParent.childElementCount);//1 //children 是一个只读的类数组对象,但它保存的是该节点的第一层元素子节点;
console.log(oParent.children);//[div#child]
console.log(oParent.children.length);//1 console.log(oParent.firstChild);//#text
console.log(oParent.firstElementChild);//<div id="child"></div> console.log(oParent.lastChild);//#text
console.log(oParent.lastElementChild);//<div id="child"></div>
</script>

同级属性

nextSibling 和 nextElementSibling

  nextSibling 是后一个节点(包括文本节点);

  nextElementSibling 是后一个元素节点;

previousSibling 和 previousElementSibling

  previousSibling 是前一个节点(包括文本节点);

  previousElementSibling 是前一个元素节点;

        <div id="parent">
<div id="child1"></div>
<div id="child2"></div>
<div id="child3"></div>
</div>
<script type="text/javascript">
var oParent = document.getElementById('parent');
var oChild2 = document.getElementById('child2'); console.log(oChild2.nextSibling);//#text
console.log(oChild2.nextElementSibling);//<div id="child3"></div> console.log(oChild2.previousSibling);//#text
console.log(oChild2.previousElementSibling);//<div id="child1"></div>
</script>

方法

hasChildNodes()

  obj.hasChildNodes() 方法在包含一个或多个子节点时返回 true,比查询 childNodes.length 是否 大于等于 1 (不等于0)更简单;

contains

  obj.contains(value) 方法接受一个节点作为参数,返回一个布尔值,表示参数节点是否为当前节点的后代节点(不一定是第一层子节点);

  IE 和 safari 不支持 document.contains() 方法,只支持元素节点的 contains() 方法;

        <div id="parent">
<div id="child1"></div>
<div id="child2"></div>
<div id="child3">123</div>
</div>
<script type="text/javascript">
var oParent = document.getElementById('parent');
var oChild2 = document.getElementById('child2');
var oChild3 = document.getElementById('child3'); console.log(oParent.hasChildNodes());//true
console.log(oChild2.hasChildNodes());//false
console.log(oChild3.hasChildNodes());//true console.log(oParent.contains(oChild2));//true
</script>

compareDocumentPosition()

  obj1.compareDocumentPosition(obj2); 方法用于确定节点 obj1 和节点 obj2 之间的关系,返回一个表示该关系的位掩码;

  •  0     两个节点相同
  • 1     两个节点不在同一个文档(即有一个节点不在当前文档)
  • 2     参数节点 obj2 在当前节点 obj1 的前面
  • 4     参数节点 obj2 在当前节点 obj1 的后面
  • 8     参数节点 obj2 包含 当前节点 obj1
  • 16    当前节点 obj1 包含 参数节点 obj2
  • 32    浏览器的私有用途

  因为返回值会相加,我们一般看返回值是否大于16,来判断当前节点 obj1 是否包含 参数节点 obj2;

        <div id="parent">
<div id="child1"></div>
<div id="child2"></div>
<div id="child3">123</div>
</div>
<script type="text/javascript">
var oParent = document.getElementById('parent');
var oChild2 = document.getElementById('child2');
var oChild3 = document.getElementById('child3'); //两节点相同
console.log(oParent.compareDocumentPosition(oParent));//0 //参数节点在在当前节点前面
console.log(oChild3.compareDocumentPosition(oChild2));//2 //参数节点在当前节点后面
console.log(oChild2.compareDocumentPosition(oChild3));//4 // 20=16+4
// 当前节点包含参数节点,并且参数节点在当前节点后面
console.log(oParent.compareDocumentPosition(oChild2));//20 // 10=8+2
// 参数节点包含当前节点,并且参数节点在当前节点前面
console.log(oChild2.compareDocumentPosition(oParent));//10
</script>

isSameNode() 和 isEqualNode()

  这两个方法都接受一个节点参数,并在 节点参数 与 引用节点 相同或相等时返回 true;

  所谓相同(same),指的是两个节点引用的是同一个对象;

  所谓相等(equal),指的是两个节点是相同的类型,具有相等的属性(nodeName、nodeValue等等),而且它们的 attributes 和 childNodes 属性也相等(相同位置包含相同的值);

  firefox 不支持 isSameNode() 方法,而 IE8 及以下两个方法都不支持;

        <div id="parent">
<div id="child1"></div>
<div id="child2"></div>
<div id="child3"></div> <div class="child"></div>
<div class="child"></div>
<div class="child">1234</div>
</div>
<script type="text/javascript">
var oParent = document.getElementById('parent');
var oChild2 = document.getElementById('child2');
var oChild3 = document.getElementById('child3'); var oChild = document.getElementsByClassName('child');
//isSameNode 指的是两个节点引用的是同一个对象;
//isEqualNode 指的是两个节点是相同的类型,具有相等的属性(nodeName、nodeValue等等),并且
       //它们的 attributes 和 childNodes 属性也相等(相同位置包含相同的值);
console.log(oParent.isSameNode(oParent));//true
console.log(oParent.isEqualNode(oParent));//true console.log(oChild2.isSameNode(oChild3));//false
console.log(oChild2.isEqualNode(oChild3));//false console.log(oChild[0].isSameNode(oChild[1]));//false console.log(oChild[0].isEqualNode(oChild[1]));//true
console.log(oChild[1].isEqualNode(oChild[2]));//false
</script>

节点操作

  DOM 提供节点操作的方法是因为 DOM 节点关系指针都是只读的;

  DOM 节点操作方法包括创建节点、插入节点、删除节点、替换节点、查看节点和复制节点。查看节点指的是查看节点之间的关系,在上面已经做过详细介绍;

createElement() 创建节点

  document.createElement() 方法可以创建新元素节点。这个方法接受一个参数,即要创建元素的标签名,这个标签名在 HTML 文档中不区分大小写;

  在IE7及以下浏览器中,创建 input 中的 button、checkbox 和 radio 可能出现兼容性问题,要单独处理下;

        <div id="wrapper"></div>
<script type="text/javascript">
var oWrapper = document.getElementById('wrapper');
var test = document.createElement('span'); oWrapper.appendChild(test);
console.log(oWrapper);//<div id="wrapper"><span></span></div>
</script>

  

插入节点

appendChild()

  appendChild() 方法用于向 childNodes 列表的末尾添加一个节点,并返回新增节点。

  如果插入的节点已经是文档的一部分了,那结果就是将该节点从原来的位置转移到新位置;

        <div id="wrapper">
<div id="child"></div>
<div id="test"></div>
</div>
<script type="text/javascript">
var oWrapper = document.getElementById('wrapper');
var oChild = document.getElementById('child');
var oTest = document.getElementById('test'); var oSpan = document.createElement('span');
oChild.appendChild(oSpan);
oChild.appendChild(oTest);
console.log(oWrapper);
//<div id="wrapper">
//<div id="child">
//<span></span>
//<div id="test"></div>
//</div>
//</div>
</script>

insertBefore()

  referenceNode.parentNode.insertBefore(newNode,referenceNode) 方法接收两个参数:要插入的节点和作为参照的节点。

  插入节点后,被插入的节点会变成参照节点的前一个兄弟节点(previousSibling),同时被方法返回。

  如果参照节点是 null,则 insertBefore() 与 appendChild() 方法执行相同的操作,在父元素结尾插入新节点。

  同样地,如果插入的节点已经是文档的一部分了,那结果就是将该节点从原来的位置转移到新位置;

        <div id="wrapper">
<div id="child1"></div>
<div id="child2"></div>
<div id="child3"></div>
</div>
<script type="text/javascript">
var oWrapper = document.getElementById('wrapper');
var oChild1 = document.getElementById('child1');
var oChild2 = document.getElementById('child2');
var oChild3 = document.getElementById('child3'); var test = document.createElement('span');
oWrapper.insertBefore(test,null);
oWrapper.insertBefore(oChild2,oChild1);
console.log(oWrapper);
//<div id="wrapper">
//<div id="child2"></div>
//<div id="child1"></div>
//<div id="child3"></div>
//<span></span>
//</div>
</script>

  由于不存在 insertAfter() 方法,如果要插在当前节点的某个子节点后面,可以用 insertBefore() 和 appendChild() 封装方法;

        <div id='oldDiv'>old</div>
<button id="btn">增加节点</button>
<script type="text/javascript">
function insertAfter(newElement,targetElement){
var parent = targetElement.parentNode;
if(parent.lastChild === targetElement){
return parent.appendChild(newElement);
}else{
return parent.insertBefore(newElement,targetElement.nextSibling);
}
} var oBtn = document.getElementById('btn');
var newDiv = document.createElement('div');
newDiv.innerHTML = '新创建DIV';
oBtn.onclick = function(){
insertAfter(newDiv,oldDiv);
}
</script>

insertAdjacentHTML() 

  insertAdjacentHTML() 方法作为终级办法,相当于前面方法的综合。该方法接收两个参数:插入的位置和要插入的HTML文本;

  第一个参数必须是下列值之一,且这些值都必须是小写形式:

  • beforebegin 在当前元素之前插入一个紧邻的同级元素;
  • afterbegin 在当前元素的第一个子元素之前再插入新的子元素;
  • beforeend 在当前元素的最后一个子元素之后再插入新的子元素;
  • afterend   在当前元素之后插入一个紧邻的同级元素;

  第二个参数是一个 HTML 字符串,如果浏览器无法解析字符串,就会抛出错误;

删除节点

removeChild()

  parentNode.removeChild(targetNode) 方法接收一个参数,即要移除的节点,被移除的节点成为方法的返回值;

remove()

  相比于 removeChild(),targetNode.remove() 方法不太常见,但是却非常简单。该方法不用调用其父节点,直接在当前节点使用 remove() 方法就可以删除该节点,无返回值;IE浏览器不支持该方法;

  remove() 方法常用于删除元素节点和文本节点,不可用于属性节点;

        <div id="wrapper">
<div id="child1"></div>
<div id="child2"></div>
<div id="child3"></div>
</div>
<script type="text/javascript">
var oWrapper = document.getElementById('wrapper');
var oChild1 = document.getElementById('child1');
var oChild2 = document.getElementById('child2');
var oChild3 = document.getElementById('child3'); oWrapper.removeChild(oChild3);
oChild2.remove();
console.log(oWrapper);
//<div id="wrapper">
//<div id="child1"></div>
//</div>
</script>

替换节点 replaceChild()

  paentNode.replaceChild(newChild,oldChild) 接收的两个参数是要插入的节点和要替换的节点,要替换的节点将由这个方法返回并从文档树中移除,同时由要插入的节点占据其位置;

        <div id="wrapper">
<div id="child1"></div>
<div id="child2"></div>
<div id="child3"></div>
</div>
<script type="text/javascript">
var oWrapper = document.getElementById('wrapper');
var oChild1 = document.getElementById('child1');
var oChild2 = document.getElementById('child2');
var oChild3 = document.getElementById('child3'); oWrapper.replaceChild(oChild3,oChild1);
console.log(oWrapper);
//<div id="wrapper">
//<div id="child3"></div>
//<div id="child2"></div>
//</div>
</script>

复制节点 cloneNode()

  cloneNode() 方法用于克隆一个节点。它接受一个布尔值作为参数,表示是否执行深复制。在参数为 true 时,执行深复制,也就是复制节点及整个子节点树。在参数为 false 的情况下,执行浅复制,即只复制节点本身。复制后返回的节点副本属于文档所有,但并没有为它指定父节点。若参数为空,也相当于 false;

  cloneNode() 方法只复制特性和子节点,不会复制添加到DOM节点中的javascript属性,例如事件处理程序等;

        <ul id="wrapper">
<li>1111</li>
<li>2222</li>
<li>3333</li>
<li>4444</li>
<li>5555</li>
<li>6666</li>
</ul>
<script>
var oWrapper = document.getElementById('wrapper');
oWrapper.abc = 0; var deepTest = oWrapper.cloneNode(true);//深复制
console.log(deepTest.children.length);//6
//cloneNode() 方法只复制特性和子节点,不会复制添加到DOM节点中的javascript属性
console.log(deepTest.abc);//undefined var shallowTest = oWrapper.cloneNode();//浅复制不复制子节点
console.log(shallowTest.children.length);//0
</script>

jacascript DOM节点——节点关系与操作的更多相关文章

  1. jacascript DOM节点——元素节点、属性节点、文本节点

    前言:这是笔者学习之后自己的理解与整理.如果有错误或者疑问的地方,请大家指正,我会持续更新! DOM节点的三个种类:元素节点.文本节点.属性节点: 元素节点 元素节点就是 HTML 标签元素,元素节点 ...

  2. DOM树节点关系

    DOM是JS中专门操作HTML页面内容的 他的三种基本使用方法是: 1.  document.getElementById(''):  ——>选取html页面中带有Id的属性名: 2.docum ...

  3. JS学习之DOM节点的关系属性封装、克隆节点、Dom中Style常用的一些属性等小结

    JS DOM节点: 在JS DOM中节点的关系被定义为节点的属性: 通常有以下几种节点之间的关系: (这里的关系是所有浏览器都支持的) parentNode    父节点 childNodes     ...

  4. DOM之节点操作

    DOM提供了很多实用的API,这些API让我们可以轻松的访问HTML文档.所谓API(应用程序接口),简单来说,就是让我们可以直接使用它访问程序的一些属性或方法,而不用了解程序内部的运作过程和原理. ...

  5. HTML DOM元素关系与操作

    <html> <head><title>DOM元素关系与操作</title></head> <body> <!-- div ...

  6. 简述HTML DOM及其节点分类

    在JavaScript中,document这个对象大家一定很熟悉,哪怕是刚刚开始学习的新人,也会很快接触到这个对象.而document对象不仅仅是一个普通的JavaScript内置对象,它还是一个巨大 ...

  7. JS魔法堂:判断节点位置关系

    一.前言 在polyfill querySelectorAll 和写弹出窗时都需要判断两个节点间的位置关系,通过jQuery我们可以轻松搞定,但原生JS呢?下面我将整理各种判断方法,以供日后查阅. 二 ...

  8. Qt树形控件QTreeView使用1——节点的添加删除操作 复选框的设置

    QtreeView是ui中最常用的控件,Qt中QTreeWidget比QTreeView更简单,但没有QTreeView那么灵活(QTreeWidget封装的和MFC的CTreeCtrl很类似,没有m ...

  9. DOM树节点和事件

    一.前言:DOM树节点是JS的基础语句.通过节点,能够取到HTML代码中的任意标签,从而对其进行修改和添加各种视觉效果. 二.DOM树节点    DOM节点分为三大类: 元素节点,属性节点,文本节点  ...

随机推荐

  1. 交换排序—快速排序(Quick Sort)

    基本思想: 1)选择一个基准元素,通常选择第一个元素或者最后一个元素, 2)通过一趟排序讲待排序的记录分割成独立的两部分,其中一部分记录的元素值均比基准元素值小.另一部分记录的 元素值比基准值大. 3 ...

  2. 使用 js 设置组合快捷键,支持多个组合键定义,还支持 React

    ╭┈┈╮ ╭┈┈╮ ╭┈┈╮ ┆ ├┈┈..┈┈┈┈┈.┆ └┈╮┆ ├┈┈..┈┈┈┈┈..┈┈.┈┈..┈┈┈┈┈. ┆ ┆┆ □ ┆┆ ┈┤┆ < ┆ -__┘┆ ┆ ┆┆__ ┈┈┤ ╰ ...

  3. [css 揭秘]:CSS揭秘 技巧(一):半透明边框

    我的github地址:https://github.com/FannieGirl/ifannie/ 源码都在上面哦 喜欢的给我一个星吧 半透明边框 css 中的半透明颜色,比如用 rgba() 和 h ...

  4. ssh框架-Struts2(一)

    Struts2 概述 用我们自己的话来说: struts是web层框架, 相当于Servlet 作用: 1. 获得请求参数 2. 调用业务 3. 分发转向 常用的WEB层框架 Struts2入门 1. ...

  5. 2017-2018-1 Java演绎法 第四五周 作业

    团队任务:撰写<需求规格说明书> 团队组长:袁逸灏 本次编辑:刘伟康 流程.分工.比例 (比例按照任务的费时.难度和完成情况估算) 流程 确定任务 -→ 分配任务 -→ 各组员完成各自任务 ...

  6. python实现朴素贝叶斯

    参考:<机器学习实战>- Machine Learning in Action 一. 基本思想  简单的说,用概率的高低来决定数据属于哪一类别,这就是贝叶斯决策理论的核心思想,即选择具有最 ...

  7. nyoj 对决

    对决 时间限制:1000 ms  |  内存限制:65535 KB 难度:0   描述 Topcoder 招进来了 n 个新同学,Yougth计划把这个n个同学分成两组,要求每组中每个人必须跟另一组中 ...

  8. 关于搭建MyBatis框架(二)

    由于在[关于使用Mybatis的使用说明(一)http://www.cnblogs.com/zdb292034/p/8675766.html]中存在不太完善地方,通过此片文档进行修订: 阅读指南:(1 ...

  9. Mongodb中 Documents文档说明

    mongodb使用BSON格式存储数据记录. 如下图: 文档结构 文档有键值对组成, 有以下结构: {    field1: value1,    field2: value2,    ...     ...

  10. 遍历JSON

    第一种: each,不做详细说明,太常用了 第二种:我用来遍历单个组,实现前端界面绑定 for(var item in person){ alert("person中"+item+ ...