因为 DOM 的存在,这使我们可以通过 JavaScript 来获取、创建、修改、或删除节点。

NOTE:下面提供的例子中的 element 均为元素节点。

获取节点

父子关系

element.parentNode

element.firstChild/element.lastChild

element.childNodes/element.children

兄弟关系

element.previousSibling/element.nextSibling

element.previousElementSibling/element.nextElementSibling

通过节点直接的关系获取节点会导致代码维护性大大降低(节点之间的关系变化会直接影响到获取节点),而通过接口则可以有效的解决此问题。

通过节点直接的关系获取节点会导致代码维护性大大降低(节点之间的关系变化会直接影响到获取节点),而通过接口则可以有效的解决此问题。

ELEMENT_NODE & TEXT_NODE

  • First
  • Second
  • Third
  • Fourth

Hello

var ulNode = document.getElementsByTagName("ul")[0];

console.log(ulNode.parentNode); //

console.log(ulNode.previousElementSibling); //null

console.log(ulNode.nextElementSibling); //

Hello

console.log(ulNode.firstElementChild); //

First

console.log(ulNode.lastElementChild); //

Fourth

NTOE:细心的人会发现,在节点遍历的例子中,body、ul、li、p节点之间是没有空格的,因为如果有空格,那么空格就会被当做一个TEXT节点,从而用ulNode.previousSibling获取到得就是一个空的文本节点,而不是

First 节点了。即节点遍历的几个属性会得到所有的节点类型,而元素遍历只会得到相对应的元素节点。一般情况下,用得比较多得还是元素节点的遍历属性。

实现浏览器兼容版的element.children有一些低版本的浏览器并不支持 element.children 方法,但我们可以用下面的方式来实现兼容。

Compatible Children Method

123

ppp

h1

function getElementChildren(e){

if(e.children){

return e.children;

}else{

/* compatible other browse */

var i, len, children = [];

var child = element.firstChild;

if(child != element.lastChild){

while(child != null){

if(child.nodeType == 1){

children.push(child);

}

child = child.nextSibling;

}

}else{

children.push(child);

}

return children;

}

}

/* Test method getElementChildren(e) */

var item = document.getElementById("item");

var children = getElementChildren(item);

for(var i =0; i < children.length; i++){

alert(children[i]);

}

NOTE:此兼容方法为初稿,还未进行兼容性测试。

接口获取元素节点

getElementById

getElementsByTagName

getElementsByClassName

querySelector

querySelectorAll

getElementById

获取文档中指定 id 的节点对象。

var element = document.getElementById('id');

getElementsByTagName

动态的获取具有指定标签元素节点的集合(其返回值会被 DOM 的变化所影响,其值会发生变化)。此接口可直接通过元素而获取,不必直接作用于 document 之上。

// 示例

var collection = element.getElementsByTagName('tagName');

// 获取指定元素的所有节点

var allNodes = document.getElementsByTagName('*');

// 获取所有 p 元素的节点

var elements = document.getElementsByTagName('p');

// 取出第一个 p 元素

var p = elements[0];

getElementsByClassName获取指定元素中具有指定 class 的所有节点。多个 class 可的选择可使用空格分隔,与顺序无关。

var elements = element.getElementsByClassName('className');

NOTE:IE9 及一下版本不支持 getElementsByClassName

兼容方法

function getElementsByClassName(root, className) {

// 特性侦测

if (root.getElementsByClassName) {

// 优先使用 W3C 规范接口

return root.getElementsByClassName(className);

} else {

// 获取所有后代节点

var elements = root.getElementsByTagName('*');

var result = [];

var element = null;

var classNameStr = null;

var flag = null;

className = className.split(' ');

// 选择包含 class 的元素

for (var i = 0, element; element = elements[i]; i++) {

classNameStr = ' ' + element.getAttribute('class') + ' ';

flag = true;

for (var j = 0, name; name = className[j]; j++) {

if (classNameStr.indexOf(' ' + name + ' ') === -1) {

flag = false;

break;

}

}

if (flag) {

result.push(element);

}

}

return result;

}

}

querySelector / querySelectorAll

获取一个 list (其返回结果不会被之后 DOM 的修改所影响,获取后不会再变化)符合传入的 CSS 选择器的第一个元素或全部元素。

var listElementNode = element.querySelector('selector');

var listElementsNodes = element.querySelectorAll('selector');

var sampleSingleNode = element.querySelector('#className');

var sampleAllNodes = element.querySelectorAll('#className');

NOTE: IE9 一下不支持 querySelector 与 querySelectorAll

创建节点

创建节点 -> 设置属性 -> 插入节点

var element = document.createElement('tagName');

修改节点

textContent获取或设置节点以及其后代节点的文本内容(对于节点中的所有文本内容)。

element.textContent; // 获取

element.textContent = 'New Content';

NOTE:不支持 IE 9 及其一下版本。

innerText (不符合 W3C 规范)获取或设置节点以及节点后代的文本内容。其作用于 textContent 几乎一致。

element.innerText;

NOTE:不符合 W3C 规范,不支持 FireFox 浏览器。

FireFox 兼容方案

if (!('innerText' in document.body)) {

HTMLElement.prototype.__defineGetter__('innerText', function(){

return this.textContent;

});

HTMLElement.prototype.__defineSetter__('innerText', function(s) {

return this.textContent = s;

});

}

插入节点

appendChild

在指定的元素内追加一个元素节点。

var aChild = element.appendChild(aChild);

insertBefore

在指定元素的指定节点前插入指定的元素。

var aChild = element.insertBefore(aChild, referenceChild);

删除节点

删除指定的节点的子元素节点。

var child = element.removeChild(child);

innerHTML

获取或设置指定节点之中所有的 HTML 内容。替换之前内部所有的内容并创建全新的一批节点(去除之前添加的事件和样式)。innerHTML 不检查内容,直接运行并替换原先的内容。

NOTE:只建议在创建全新的节点时使用。不可在用户可控的情况下使用。

var elementsHTML = element.innerHTML;

存在的问题+

低版本 IE 存在内存泄露

安全问题(用户可以在名称中运行脚本代码)

PS: appendChild() , insertBefore()插入节点需注意的问题使用appendChild()和insertBefore()插入节点都会返回给插入的节点,

//由于这两种方法操作的都是某个节点的子节点,所以必须现取得父节点,代码中 someNode 表示父节点

//使用appendChild()方法插入节点

var returnedNode = someNode.appendChild(newNode);

alert(returnedNode == newNode) //true

//使用insertBefore()方法插入节点

var returnedNode = someNode.appendChild(newNode);

alert(returnedNode == newNode) //true

值得注意的是,如果这两种方法插入的节点原本已经存在与文档树中,那么该节点将会被移动到新的位置,而不是被复制。

adscasdjk
adscasdjk

var t = document.getElementById("test");

var a = document.getElementById('a');

//var tt = a.cloneNode(true);

t.appendChild(a);

在这段代码中,页面输出的结果和没有Javascript时是一样的,元素并没有被复制,由于元素本来就在最后一个位置,所以就和没有操作一样。如果把id为test的元素的两个子元素点换位置,就可以在firbug中看到这两个div已经被调换了位置。

如果我们希望把id为a的元素复制一个,然后添加到文档中,那么必须使被复制的元素现脱离文档流。这样被添加复制的节点被添加到文档中之后就不会影响到文档流中原本的节点。即我们可以把复制的元素放到文档的任何地方,而不影响被复制的元素。下面使用了cloneNode()方法,实现节点的深度复制,使用这种方法复制的节点会脱离文档流。当然,我不建议使用这种方法复制具有id属性的元素。因为在文档中id值是唯一的。

adscasdjk
adscasdjk

var t = document.getElementById("test");

var a = document.getElementById('a');

var tt = a.cloneNode(true);

t.appendChild(tt);

相似的操作方法还有 removeNode(node)删除一个节点,并返回该节;replaceNode(newNode,node)替换node节点,并返回该节点。这两种方法相对来说更容易使用一些。

html dom节点源码,JavaScript操作HTML DOM节点的基础教程相关推荐

  1. html dom节点源码,HTML DOM HTML DOM 节点 - 闪电教程JSRUN

    在 HTML DOM 中,所有事物都是节点.DOM 是被视为节点树的 HTML. DOM 节点 根据 W3C 的 HTML DOM 标准,HTML 文档中的所有内容都是节点: 整个文档是一个文档节点 ...

  2. javascript html dom,javascript 操作 HTML DOM

    主要概述一些有用的基础的DOM的方法以及怎样用使用javascript使用它们. 可以实现比如动态地新建控制移动HTML元素. Document 对象的常用方法 1.getElementById(id ...

  3. JavaScript 操作 HTML DOM (文档对象模型) 相关知识点

    HTML DOM 树 通过可编程的对象模型,JavaScript 获得了足够的能力来创建动态的 HTML. JavaScript 能够改变页面中的所有 HTML 元素 JavaScript 能够改变页 ...

  4. JavaScript操作的DOM对象

    什么叫DOM? DOM是文档对象模型(Document Object Model,是基于浏览器编程(在本教程中,可以说就是DHTML编程)的一套API接口,W3C出台的推荐标准,每个浏览器都有一些细微 ...

  5. storm-hbase jar包中的bolt节点源码解析

    一段时间内,大家都是自己在storm的节点中实现对hbase的操作,不管是普通的topo还是在trident中都是这样:不知道从那个版本起,在storm的压缩包中就多出了好几个jar包,把针对habs ...

  6. dom对html增删改操作,6.DOM对HTML元素的增删改操作

    节点的增删改操作 function createNode(){ //创建一个li元素 var li = document.createElement("li"); li.inner ...

  7. python飞机大战源码素材包_小甲鱼python基础教程飞机大战源码及素材

    原博文 2018-12-22 23:32 − 百度了半天小甲鱼python飞机大战的源码和素材,搜出一堆不知道是什么玩意儿的玩意儿. 最终还是自己对着视频一行行代码敲出来. 需要的同学点下面的链接自取 ...

  8. 基础操作案例 :ArcGIS PRO基础教程(一)

    操作要求 1.面积为50-80亩 2.不能选在有耕地.园地内 3.坡度小于15度,高程在以下1930 4.距离水源地在300米以内 已知数据 1.等高线图 CONTOUR 2.土地利用图 parcel ...

  9. 基础操作案例:ArcGIS PRO基础教程(二)

    操作要求 对Pnt按kriging(克里格插值),获得整个范围的ph分布图 按地块,zonal statistics统计地块的PH属性表 属性关联 更新字段PH 操作步骤 已知:有采样点的PH,在pn ...

最新文章

  1. 又一起“删库”:链家程序员怒删公司 9TB 数据,被判 7 年
  2. 标准C++的类型转换符:static_cast、dynamic_cast、reinterpret_cast和const_cast(转载)
  3. python将一行作为字段_关于python:Django admin在同一行显示多个字段
  4. sql年月日24小时制_24小时制的「无码」真人秀,令人叫绝
  5. CF 717A Festival Organization——斯特林数+递推求通项+扩域
  6. webpack打包后引用cdn的js_手摸手 Webpack 多入口配置实践
  7. cesium3dtiles位置改变
  8. 终于转了,写写人生学习规划
  9. 给hadoop 2.7.1 定制树莓派参数
  10. CentOS6.x定制~修改CentOS字样
  11. 【转载】C++引用详解
  12. pyqt5 tablewidget 设置行高_Python+PyQt5基础开发(10)
  13. 欺骗的艺术----(2)
  14. 什么是php探针,以及雅黑探针使用教程
  15. HTML二级下拉菜单自动联动,html二级联动下拉菜单 [Excel函数如何制作二级联动下拉菜单]...
  16. 哎,为了在vs上开发或调试linux,各种跪啊。而且后面还有更多……
  17. 后端返给前端的数据格式
  18. 高德API 经纬度转换地市区县(含读取文件)
  19. rosnode not fount 报错解决
  20. 十大管理之项目成本管理知识点

热门文章

  1. python字符串逆序_python之字符串逆序
  2. 博图wincc连接数据块_西门子博途WINCC 可通过创建画面模板提高编程效率
  3. alexnet训练多久收敛_AlexNet浅析
  4. 修改unity变量名但不丢失序列化值
  5. Flask 知识总结
  6. Python3实现TCP端口扫描器
  7. spring + shiro + cas 实现sso单点登录
  8. 计数排序之python 实现源码
  9. 我积累的数据库操作类(ASP.NET)
  10. 几种网站后门排查 不全面