js Dom(Document Object Model) 节点树 DOM树 document 方法(创建,插入,删,替换) dom题目

定义

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

document 方法

document 代表整个文档

获取标签

// id  IE8以下id不区分大小写 也返回name='id' 的元素
document.getElementById(‘id’)  
// 标签名
document.getElementsTagName('div') 
// 类名 ie9以下没有
document.getElementsClassName()
// 标签name属性  `<div name="hh"></div>`
document.getElementsByName(‘hh’) 
// css选择器 ie8以下没有 选出的元素不是实时的(动态移除该元素后 选出的该元素还在)
document.querySelector() 
// css选择器 ie8以下没有
document.querySelectorAll() 

document.getElementsByTagName('*');//选择所有标签

创建节点

// 创建元素节点
document.createElement('div');
// 创建文本节点
document.createTextNode('文本节点内容');
// 创建注释节点
document.createComment('注释节点内容');
// 创建DocumentFragment(文档碎片)节点
document.createDocumentFragment();

插入节点
parentNode.appendChild(); //剪切操作

var div = document.createElement('div');
document.body.appendChild(div);// 把div插入body的底部

parentNode.insertBefore(a,b);// 一定要父级调用

// html
<div>
	<span></span>
</div>
//js
var div = document.getElementsByTagName('div')[0],
	span = div.getElementsByTagName('span')[0],
	text = document.createElement('div');
	
div.insertBefore(text,span);// 在div下面 span 之前插入text

删除节点
parent.removeChild();
child.remove();

//html 同上
div.removeChild(span);//移除div下面的span 返回span  没有销毁,相当于剪切出来
div.remove(); // 移除div 返回undefined

替换节点
parent.replaceChild(new,origin);//拿 new 替换 origin 返回origin

//html 同上
div.replaceChild(text,span);

Element 节点一些属性 方法

innerHTML 获取节点的html结构 可读写
innerText(火狐不兼容)/textContent(老版本IE不好使) 获取节点的文本内容 可读写

setAttribute(‘id’,‘idName’);//设置节点属性
getAttribute(‘id’);//获取节点属性

节点树

遍历节点树 (文本节点 元素节点 注释节点 )

parentNode 父节点
childNodes 子节点们
firstChild 第一个子节点
lastChild 最后一个子节点
nextSibling 后一个兄弟节点
previousSibling 前一个兄弟节点

遍历元素节点树

parentElement 返回当前节点的父节点 (IE9不兼容)
children 只返回当前节点的子节点
node.childElementCount === node.children.length 当前元素节点的子元素个数(IE9不兼容)
firstElementChild 返回第一个元素子节点(IE9不兼容)
lastElementChild 返回最后一个元素子节点(IE9不兼容)
nextElementSibling 返回后面一个兄弟元素 (IE9不兼容)
previousElementSilbling 返回前面一个兄弟元素 (IE9不兼容)

节点的四个属性

nodeName 节点名称 ,只读
nodeValue 文本节点或Comment(注释)节点的文本内容 可读写
nodeType 节点类型 ,只读
元素节点 1,属性节点 2,文本节点 3,注释节点 8 ,document 9,DocumentFragment 11

//html 
<div id="div" class="class"></div>

//js
var div = document.getElementsByClassName('class')[0];
div.attributes;//{0: id,1:class,length:2}
div.attributes[0];// id="div"
div.attributes[0].nodeType;// 2  //属性节点
div.attributes[0].value;// div
div.attributes[0].name;// id

attributes Element节点的属性集合

节点方法 node.hasChildNodes()

判断有没有子节点(所有类型节点) node.hasChildNodes()

document 与 Document HTMLDocument

document 是文档节点 对象
Document 是构造函数(不能new Document ,系统自己用)
在这里插入图片描述
document 不是 Document 直接构造出来的
document 是 HTMLDocument 构造出来的

Document.prototype.abc = "abc"
HtmlDocument.prototype.bcd = "bcd "
document.abc;// "abc"
document.bcd;// "bcd"

//-----------
HTMLDocument.prototype = {
	...
	__porto__ : Document.prototype
}
document.prototype = {
	...
	__porto__ : HTMLDocument.prototype
}
DOM树

继承关系 向上继承

  • Node
    • Document
      • HTMLDocument
        • document
      • XMLDocument
    • CharacterData
    • Element
      • HTMLElement(HTML节点)
        • HTMLHeadElement
        • HTMLBodyElement
        • HTMLDivElement
      • XMLElement
    • Attr
HTMLBodyElement.prototype.abc = "abc"
var body = document.getElementsByTagName('body')[0];
var head = document.getElementsByTagName('head')[0];
body.abc;//"abc"
head.abc;//undefined
Node.__proto__; //EventTarget()
Node.__proto__.proto__;//Object.Prototype (最终原型对象)

getElementById 方法定义在 Document.peototype 上
getElementsByName 方法定义在 HTMLDocument.peototype 上 即XML节点不能调用该方法
getElementsByTagName 方法定义在 Document.peototype 和 Element.prototype 上

// html
<div>
	<span></span>
</div>

//js
var div = document.getElementsByTagName('div')[0];
var span = div.getElementsByTagName('span')[0];

HTMLDocument.peototype 定义了一些常用的属性 body,head分别指代文档中的 <body><head>标签
Document.prototype 上定义了 documentElement 属性 指代文档的根元素,在Html文档中,总是指代<html>元素

document.body;// body标签
document.documentElement;// html标签

getElementsByClassName/queruSelector/queruSelectorAll 在 Document.prototype 和 Elemenet.prototype 上都有定义

题目
遍历元素节点树(在原型链上)

题意:1,给父节点,遍历所有子节点
2,打印层级结构(向下)

1,给父节点,遍历所有子节点

Element.prototype.tree = function(){
	return this.childNodes
}
// document.body.tree()

2,打印层级结构(线下)
// 包含所有类型节点

Element.prototype.tree2 = function(){
    var nodes = this.childNodes,
        obj = {
            name: this,
            length: 0,
            push: Array.prototype.push,
            splice: Array.prototype.splice
        }
    treee(nodes,obj)
    function treee(nodes,obj){
        var len = nodes.length;
        for(var i = 0;i < len; i++){
            if(nodes[i].nodeType == 1){ //元素节点
                if(nodes[i].childNodes){
                    var obj1 = {
                        name:nodes[i],
                        length:0,
                        push: Array.prototype.push,
                        splice: Array.prototype.splice
                    }
                    obj.push(obj1)
                    treee(nodes[i].childNodes,obj1)
                }
            }else{
                obj.push(nodes[i])
            }
        }
    }
    return obj
}
// document.body.tree2()

// 只包含元素节点

Element.prototype.tree3 = function(){
    var nodes = this.childNodes,
        obj = {
            name: this,
            length: 0,
            push: Array.prototype.push,
            splice: Array.prototype.splice
        }
    treee(nodes,obj)
    function treee(nodes,obj){
        var len = nodes.length;
        for(var i = 0;i < len; i++){
            if(nodes[i].nodeType == 1){ //元素节点
                if(nodes[i].childNodes){
                    var obj1 = {
                        name:nodes[i],
                        length:0,
                        push: Array.prototype.push,
                        splice: Array.prototype.splice
                    }
                    obj.push(obj1)
                    treee(nodes[i].childNodes,obj1)
                }else{
                    obj.push(nodes[i])
                }
            }
        }
    }
    return obj
}
// document.body.tree3()
封装函数,返回元素e的第n成祖先元素节点
function parents(e,n){
    n = n || 1;
    for(var i = 0; i < n; i++){
    	e = e ? e.parentElement : e
    }
    return e
}
封装函数,返回元素e的第n个兄弟节点 n为正,返回后面的兄弟元素节点,n为负,返回前面的兄弟节点 0 返回本身
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <div>
        <span>1</span>
        <span>2</span>
        <span>3</span>
    </div>

    <script>
        var span = document.getElementsByTagName('span')[1],
            div = document.getElementsByTagName('div')[0];

// 不兼容 IE9 及以下版本

function sibling(node,n){
    n = n || 0,
    len = Math.abs(n); //返回绝对值
    for(var i = 0; i < len; i++){
        if(node){
            node = n > 0 ? node.nextElementSibling : node.previousElementSibling
        }
    }
    return node
}
// console.log(sibling(span,1))

// 兼容 IE9 及以下版本

function siblingCompatibility(node,n){
	n = n || 0,
	len = Math.abs(n); //返回绝对值
	for(var i = 0; i < len; i++){
	    if(node){
	    	// node = n > 0 ? nextPrev(node.nextSibling,'next') : nextPrev(node.previousSibling,'prev')
	     	// 或
	        if(n > 0){
               node = node.nextElementSibling ? node.nextElementSibling : nextPrev(node.nextSibling,'next')
            }else{
                node = node.previousElementSibling ? node.previousElementSibling : nextPrev(node.previousSibling,'prev')
            }
	    }
	}
	function nextPrev(node,type){
	    if(node.nodeType != 1 && node != null){
	        node = type == 'next' ? nextPrev(node.nextSibling,'next') : nextPrev(node.previousSibling,'prev')
	    }
	    return node
	}
	return node
}
console.log(siblingCompatibility(span,0))

function siblingCompatibility(node,n){
    n = n || 0,
    len = Math.abs(n); //返回绝对值
    for(var i = 0; i < len; i++){
        if(node){
            if(n > 0){
                if(node.nextElementSibling){ 
                    node = node.nextElementSibling
                }else{
                    for(node = node.nextSibling; node && node.nodeType != 1; node = node.nextSibling);
                }
            }else{
                if(node.previousElementSibling){ 
                    node = node.previousElementSibling
                }else{
                    for(node = node.previousSibling; node && node.nodeType != 1; node = node.previousSibling);
                }
            }
        }
    }
    return node
}
console.log(siblingCompatibility(span,3))
    </script>
</body>
</html>
编辑函数 ,封装 myChildren功能,解决以前部分浏览器的兼容性问题,模仿children功能,不可用children属性
Element.prototype.myChildren = function(){
		var node = this.childNodes,
		len = node .length,
		obj = {
			length: 0,
			push: Array.prototype.push,
			splice: Array.prototype.splice
		}
	for(var i = 0;i<len ;i++){
		node[i].nodeType == 1 ? obj.push(node[i]):""
	}
	return obj
}

封装自己的hasChildNodes()方法,不可用children属性

判断 节点有没有该子节点

function myHasChildNodes(father,son){
    var nodes = father.childNodes,
        len = nodes.length;
    for(var i =0; i<len; i++){
        if(nodes[i] == son){
            return true 
        }
    }
    return false
}
console.log(myHasChildNodes(div,span))
封装insertAfter() 功能类似insertBefore();
Element.prototype.insertAfter = function(target,after){
     var before = after.nextElementSibling || next(after);
     if(before){
         this.insertBefore(target,before)
     }else{
         this.appendChild(target)
     }
     function next(after){
         var _next = after.nextSibling;
         if(_next == null || _next.nodeType == 1){
             return _next
         }else{
             return next(_next)
         }
     }
 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值