一、DOM继承树

DOM——Document Object Model

DOM定义了表示修改文档所需要的方法。DOM对象即为宿主对象,由浏览器厂商定义,用来操作html和xml的一类厂商定义,也有人称DOM是对HTML以及xml的标准编程接口。

继承树模型图:

1.document继承于HTMLDocument,而HTMLDocument继承于Document;

2.文本节点对象Text与注释节点对象Comment继承于CharacterData

3.在Element节点下其实存在两个子节点,除了HTMLElement节点以外还有一个XMLElement节点。

二、DOM的基本操作

1.getElementById方法定义在Document.prototype上,也就是说Element节点上不能调用这个方法。

2.getElementsByName方法定义在HTMLDocument.prototype上,即非HTML标签不能使用。

3.getElementsByTagName方法定义在Document.prototype和Element.prototype上。

<div>
<span>a</span>
</div>
<script type="text/javascript">
var div = document.getElementsByTagName("div")[0];
var span = div.getElementsByTagName("span")[0];
console.log(span);
</script>

上面示例的代码中获取元素的方法看名称好像是同一个,其实不然,获取div的getElementsByTagName是由document对象向父级的父级Document原型获取的。而获取span的getElementsByTagName是Element对象(准确说应该是HTMLElement对象)div从父级的父级Element原型上获取的。

4.HTMLDocument.prototype上定义了一些常用的属性,body、head分别指向html文档中的<body>、<head>标签。也就是说在需要获取<body>、<head>标签时不再需要调用获取元素节点的方法,而是可以直接的通过document上的body和head的属性就可以了。

var body = document.body;
var head = document.head;

如果这两行代码在全局作用域上,这两行代码都是多此一举,因为全局作用域就是就是document。可以直接使用这两个属性。

5.Document.prototype上定义了documentElement属性,指代文档的根元素,在HTML文档中,他总是指代<html>元素。

6.getElementsByClassName、querySelectorAll、querySelector在Document.prototype和Element.prototype中均有定义。

三、关于DOM节点操作的一些习题

1.遍历元素节点树

var fChildNode = function(node){
var child = node.childNodes,
childText = "",
len = child.length;
for(var i = 0; i < len; i++){
if(child[i].nodeType == 1){
childText += child[i].nodeName + " ";
if(child[i].childElementCount > 0){
fChildNode(child[i]);
}
}
}
console.log(childText);
}
//这里需要注意不要使用内置的children来直接获取子元素节点,IE9以下不兼容
//chidElementCount在很多手册上都找不到,这个属性是用来获取元素的子元素个数的

2.封装函数,返回元素e的第n层祖先元素节点

var retParent = function(elem,n){
while(elem && n){
elem = elem.parentNode;
if(elem.nodeType == 1){
n --;
}
}
return elem;
}
//这里注意不要使用parentElement这个属性,IE9以下不兼容

3.封装函数,返回元素e的第n个兄弟元素节点,n为正,返回后面的兄弟元素节点,n为负,返回前面的,n为0,返回自己

function retSibling(elem,n){
while(elem && n){
if(n > 0){
if(elem.nextElementSibling){
elem = elem.nextElementSibling;
}else{
elem = elem.nextSibling;
for(elem = elem.nextSibling; elem && elem.nodeType != 1; elem= elem.nextSibling);
}
n --;
}else{
if(elem.previousElementSibling){
elem = elem.previousElementSibling;
}else{
for(elem = elem.previousSibling; elem && elem.nodeType != 1; elem = elem.previousSibling);
}
n ++;
}
}
return elem;
}

4.写一个node.retChildren方法,功能与node.children方法一致

function retChildren(){
var children = this.childNodes;
var len = chileren.length;
var temp = {
push:Array.prototype.push,
splice:Array.prototype.splice
}
for(var i = 0; i < len; i++){
if(children[i].nodeType == 1){
temp.push(children[i]);
}
}
return temp;
}

5.在原型上封装一个hasChildren方法用来判断元素是否含有子元素

Element.prototype.myHasChildren = function (){
var children = this.childNodes;
var len = children.length;
for(var i = 0; i < len; i++){
if(childern.nodeType == 1){
return true;
}
}
return false;
}

四、增加与插入节点

  创建元素节点:document.createElement();

  创建文本节点:docuemtn.createTextNode();

  创建注释节点:document.createComment("注释内容");

  元素内插入节点:element.appendChild(插入的对象);— —类似剪切操作

  在元素下的子节点b前面插入a节点:element.insertBefore(a,b);

五、删除与替换节点

  在某个元素节点下移除,该方法会返回被移除的节点:element.removeChild(node);

  删除元素节点自身:remove();

  用新的节点new替换原来的origin节点:element.replaceChild(new,origin);

六、Element对象的一些属性

  读写节点内容操作:innerHTML;— —以字符串的方式

  读写节点文本内容操作:innerText;— —火狐不兼容

                textContent;— —老版本IE不好使

七、关于DOM节点增删改的一些练习

1.请编写一段JavaScript脚本生成下面这段DOM结构。要求:使用标准的DOM方法和属性。

var div = docuemnt.createElement("div");
var p = document.createElement("p");
var text = document.createTextNode("我最帅");
div.setAttribute("class","slogan");
div.setAttribute("class","example");
p.appendChild(text);
div.appendChild(p);

2.封装函数insertAfter();功能类似insertBefore();

即在元素节点下的一个子节点后面插入一个元素节点

Element.prototype.insertAfter = function(targetNode,afterNode){
for(afterNode = afterNode.nextSibling; afterNode && afterNode.nodeType != 1;afterNode = afterNode.nextSibling);
if(afterNode.type != 1){
this.appendChild(targetNode);
}else{
this.insertbefore(targetNode,afterNode);
}
}

3.将目标节点内部的节点顺序逆序。

//不兼容IE写法
Element.prototype.reversedChild = function(){
var children = this.children;
var len = children.length;
for(var i = len; i > 0; i--){
this.appendChild(children[i]);
}
}
//兼容IE写法
Element.prototype.reversedChild = function(){
var childNodes = this.childNodes;
for(var i = childNodes.length; i > 0 ; i--){
if(childNodes.nodeType == 1){
this.appendChild(childNodes[i]);
}
}
}

js学习总结:DOM节点二(dom基本操作)的更多相关文章

  1. D3.js学习笔记(一)——DOM上的数据绑定

    开始学习D3.js,网上没有找到很满意的中文教程,但是发现了一个很好的英文教程,讲解的非常详细.从一个初始简单的HTML网页开始,逐步加入D3.js的应用,几乎是逐句讲解.学习的时候,就顺便翻译成中文 ...

  2. js学习笔记之日期倒计时DOM操作

    1.访问html元素 getElementById() 方法  返回对拥有指定 id 的第一个对象的引用,只有dom对象有效 getElementsByName() 方法  返回指定名称的对象集合 g ...

  3. JS学习笔记(一)DOM事件和监听

    将事件绑定到元素身上的三种方法: 1.HTML事件处理程序(不推荐使用) 1 <a onclick="hide()"> 2.传统的DOM事件处理程序 即在目标DOM事件 ...

  4. DOM节点(二):操作节点

    appendChild() 用于向childNodes列表的末尾添加一个节点. var returnedNode = someNode.appendChild(newNode); 如果传入的节点已经是 ...

  5. Vue.js学习使用心得(二)——自定义指令

    自定义指令 除了核心功能默认内置的指令,Vue 也允许注册自定义指令. 自定义指令可以定义全局指令,也可以定义局部指令. 使用 directives 选项来自定义指令. 定义全局指令: <div ...

  6. JS学习笔记:(二)回流和重绘

    在搞清楚回流和重绘的概念之前,我们要清除浏览器的渲染过程. 解析生成DOM Tree(此时包含所有节点,包括display:none); 根据CSS Object Module(CCSSOM)计算节点 ...

  7. js学习笔记16----父节点的操作

    1.元素.parentNode : 只读属性,获取当前元素的父节点. 2.元素.offsetParent : 只读属性,获取离当前元素最近的一个有定位属性(position为relative或者abs ...

  8. js学习笔记15----子节点和兄弟节点的操作

    1.元素.firstChild : 只读属性,第一个子节点 标准下:会包含文本类型的子节点. 非标准下:只包含元素类型子节点. 元素.firstElementChild : 只读属性,第一个元素子节点 ...

  9. js学习笔记10----字符串的基本操作

    1.字符串的基本操作如下: 定义字符串: var str = "Hello World!" 字符串的基本操作如下: str.length-----返回字符串长度,这里返回12 st ...

随机推荐

  1. 【XSY2701】异或图 线性基 容斥原理

    题目描述 定义两个图\(G_1\)与\(G_2\)的异或图为一个图\(G\),其中图\(G\)的每条边在\(G_1\)与\(G_2\)中出现次数和为\(1\). 给你\(m\)个图,问你这\(m\)个 ...

  2. 【BZOJ4033】【HAOI2015】树上染色 树形DP

    题目描述 给你一棵\(n\)个点的树,你要把其中\(k\)个点染成黑色,剩下\(n-k\)个点染成白色.要求黑点两两之间的距离加上白点两两之间距离的和最大.问你最大的和是多少. \(n\leq 200 ...

  3. 【XSY1529】小Q与进位制 分治 FFT

    题目大意 ​ 小Q发明了一种进位制,每一位的变化范围是\(0\)~\(b_i-1\),给你一个这种进位制下的整数\(a\),问你有多少非负整数小于\(a\).结果以十进制表示. ​ \(n\leq 1 ...

  4. 【BZOJ4316】小C的独立集(动态规划)

    [BZOJ4316]小C的独立集(动态规划) 题面 BZOJ 题解 考虑树的独立集求法 设\(f[i][0/1]\)表示\(i\)这个点一定不选,以及\(i\)这个点无所谓的最大值 转移\(f[u][ ...

  5. 【UOJ#340】【清华集训2017】小 Y 和恐怖的奴隶主(矩阵快速幂,动态规划)

    [UOJ#340][清华集训2017]小 Y 和恐怖的奴隶主(矩阵快速幂,动态规划) 题面 UOJ 洛谷 题解 考虑如何暴力\(dp\). 设\(f[i][a][b][c]\)表示当前到了第\(i\) ...

  6. 【转】Ubuntu 64位系统安装交叉编译环境一直提醒 没有那个文件或目录

    安装交叉编译环境搞了一个晚上 一直提示 root@zqs-pc:~# arm-linux-gcc/usr/local/arm/4.3.2/bin/arm-linux-gcc: 行 3: /usr/lo ...

  7. django从零开始-模板

    1.应用中添加模板 INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contentt ...

  8. java ssl 使用不同的加密套件,对性能影响很大

    一直以来都是使用java默认的[加密套件]来处理ssl请求,突然有一天我尝试显式的设置了一组加密套件后,发现图片显示的速度明显快了一倍左右. 经过使用几组不同的加密套件测试后,发现使用 TLS_ECD ...

  9. 认识Jmeter工具

    1.Apache jmeter 是一个100%的纯java桌面应用,是Apache组织开发的基于java的压力测试工具.它最初被设计用于Web应用测试但后来扩展到其他测试领域,可以用于对静态的和动态的 ...

  10. python之网络编程--锁、信号量、线程、队列

    一.线程,可以发现顺序执行比开线程执行时间要短.原因是,一个进程中的多线程处理,由于存在GIL,并且GIL中只能存在一个线程,加上线程又存在切换的问题,所以时间耗得多.想要解决这个问题,是开几个进程, ...