DOM文档对象模型

DOM:文档对象模型

作用: 使javascript有能力操作HTML文档(获取HTML标记元素,添加HTML标记元素,删除HTML标记元素等)
属性:内置属性和非内置属性(自定义属性)

DOM的分类:
    核心 DOM
        提供了操作HTML元素的属性和方法
        遍历DOM树、添加新节点、删除节点、修改节点

    HTML DOM
        提供了查找改变HTML元素的属性和方法
        以一种简便的方法访问DOM树

    CSS DOM
        提供了操作CSS的属性和方法

    事件 DOM  
        事件对象模型,eg:onclick

DOM树:
在这里插入图片描述

节点关系:
    根节点:一个HTML文档只有一个根,它就是HTML节点。
    子节点:某一个节点的下级节点。
    父节点:某一个节点的上级节点。
    兄弟节点:两个子节点同属于一个父节点。

节点的分类:
    【属性节点(attribute)】,指定是HTML标签的属性
    【文本节点(text)】,指定是HTML标签的内容
    【空白节点】,在主流浏览器中标签和标签之间的换行会理解为一个空白节点,在IE浏览器中不会

下面来详细的讲解:

一、DOM选择器

 getElementById(id)    
     描  述:获取网页指定id名字的元素,返回一个对象
     语  法:var obj = document.getElementById("id名称")
     参  数:id名称(注:需要加引号)
     返回值:对象,对象的属性就是HTML标签的属性

 getElementsByTagName() 
     功  能:获取网站指定标签名称的元素
     语  法:var obj = document.getElementsByTagName("标签名称")
     参  数:标签名称(注:需要加引号)
     返回值:返回一个集合(数组),集合中每个元素都是一个单独标签对象

 getElementsByName()
     功  能:通过标签的name值获取元素
     语  法:var obj = document.getElementsByName() ("标签name名称")
     参  数:标签的name名称(注:需要加引号)
     返回值:返回值是数组,通常用来获取有name的input的值

 getElementsByClassName()
     功  能:通过class名获取元素
     语  法:var obj = document.getElementsByClassName()  ("标签的class属性名称")
     参  数:标签的class属性名称(注:需要加引号)
     返回值:返回值是数组
     
 ES5选择器:(可以直接填写,eg:标签名,类名,id名称)
     document.querySelector();          //返回匹配到的第一个元素
     
     document.querySelectorAll();       //返回一个数组,哪怕只有一个元素

 注:
     1.不是所有标签都有name值
     2.在低版本的浏览器中,getElementsByName和getElementsByClassName有兼容性
//body
	<div id="a" class="ab">aa ab</div>
	<div class="ab">abab</div>
	<span>span1span</span>
	<span>span2span</span>
	<input type="button" value="button" name="btn" >

//js
	var aObj = document.getElementById("a")
	console.log(aObj);   //<div id="a" class="ab">aa ab</div>
	
	var spanObj = document.getElementsByTagName("span");
	//console.log(spanObj);
	console.log(spanObj[0]);
	
	var btnObj = document.getElementsByName("btn");
	//console.log(btnObj);
	console.log(btnObj[0]);
	
	var abObj = document.getElementsByClassName("ab");
	//console.log(abObj);  
	console.log(abObj[1]);  
	
	
	var Obj1 = document.querySelector("#a");
	var Obj2 = document.querySelector(".ab");
	var Obj3 = document.querySelector("span");
	console.log(Obj1);
	console.log(Obj2);
	console.log(Obj3);
	
	var   Objo1 = document.querySelectorAll("span");
	var   Objo2 = document.querySelectorAll(".ab");
	// console.log(Objo1);
	console.log(Objo1[1]);
	// console.log(Objo2);
	console.log(Objo2[0]);

二、DOM属性

1.内置属性

内置属性可以直接通过点"."进行操作
   tagName               //返回值是当前元素的标签名
   innerHTML/innerText  //返回值是当前元素的内容
   id                    //返回值是当前元素的ID
   title                 //获取title的标签值,这个title是从document中获取的
   className             //返回值是当前元素的class
   href                  //返回值是当前的href的值
   以上这些属性既可以获取,也可以设置

2.非内置属性(自定义属性)

非内置属性需要通过一些节点的方法进行操作,注意:节点的方法,前缀一定是节点
   getAttribute(name)        //获取指定对象的属性名的属性值
       console.log(obox.getAttribute("num"))
   setAttribute(name,value)        //设置/修改 元素的属性,低版本的IE不兼容;接收两个参数,属性名和属性值
       obox.setAttribute("num","110")
   removeAttribute(name)     //删除 元素的属性,低版本的IE不兼容
       obox.removeAttribute("num")
//body
	<input type="text" name="ipt" value="10">
	<span num="10" id="sp">222</span>
//js
	var ipt = document.getElementsByName("ipt")[0];
	var sp = document.getElementById("sp");
	//获取属性值
	console.log(sp.getAttribute("num"));
	//修改属性值
	sp.setAttribute("num",110);
	console.log(sp);
	ipt.setAttribute("value",20);
	console.log(ipt);
	//删除元素属性
	sp.removeAttribute("num")
	console.log(sp)

三、节点

根据DOM规定,HTML文档中的每个成分都是一个节点。
 	DOM是这样规定的:
        整个文档是一个   文档节点
        每个HTML标签是一个   元素节点
        包含在HTML元素中的文本是   文本节点
        每一个HTML属性是一个   属性节点
        注释属于   注释节点
        
  相当于HTML文档中的所有内容都是节点,元素是节点的别称,节点包含元素,当然节点还有好多细化的种类
节点节点类型(nodeType)节点名字(nodeName)节点值(nodeValue)
元素节点1标签名null
文本节点3#text文本
注释节点8#comment注释的文字
文档节点9#documentnull
属性节点2属性名属性值
//body
	<ul class="a" id="b" zidingyi="c">
		文本
		<li>1</li>
		<li>2</li>
		<!-- 注释 -->
		<li>3</li>
	</ul>
//js
	var ulObj = document.getElementsByTagName("ul")[0];
	console.log(ulObj);

	var child = ulObj.childNodes;
	console.log(child);	//9个节点 [text, li, text, li, text, comment, text, li, text]
	
	console.log(ulObj.children);	//[li, li, li]

	//节点类型--》节点名字--》节点值
	// nodeType只能获取不能设置
	// nodeName只能获取不能设置
	// nodeValue 能获取能设置
	console.log(typeof child[0]);		//object
	console.log(child[0].nodeType);		//3,表示文本
	console.log(child[0].nodeName);		// #text
	console.log(child[0].nodeValue);		// 文本

	console.log(typeof child[1]);		//object
	console.log(child[1].nodeType);		//1,表示元素
	console.log(child[1].nodeName);		// LI
	console.log(child[1].nodeValue);		// null

	console.log(typeof child[5]);		//object
	console.log(child[5].nodeType);		//8,表示注释
	console.log(child[5].nodeName);		// #comment
	console.log(child[5].nodeValue);		// 注释

	//返回元素的根节点
	var liObj = document.getElementsByTagName("li")[0];
	console.log(liObj.ownerDocument);		//#document
	console.log(ulObj.ownerDocument);		//#document
	console.log(liObj.ownerDocument.nodeType);		//9,表示文档
	console.log(liObj.ownerDocument.nodeName);		// #document
	console.log(liObj.ownerDocument.nodeValue);		// null


	//节点属性
	var oAttr = ulObj.attributes;
	console.log(oAttr);	//{0: class, 1: id, 2: zidingyi, class: class, id: id, zidingyi: zidingyi, length: 3}

	console.log(oAttr[0]);	//class="a"  
	console.log(oAttr[0].nodeName);	//class
	console.log(oAttr[0].nodeValue);	//a
	console.log(oAttr[0].nodeType);		//2

	console.log(oAttr[1]);	//id="b"
	console.log(oAttr[1].nodeName);		//id
	console.log(oAttr[1].nodeValue);		//b
	console.log(oAttr[1].nodeType);		//2

	console.log(oAttr[2]);	//zidingyi="c"
	console.log(oAttr[2].nodeName);		//zidingyi
	console.log(oAttr[2].nodeValue);		//c
	console.log(oAttr[2].nodeType);		//2

获取DOM节点:

   对象.parentNode    //获得父元素节点

   对象.children      //获得子元素节点的集合,不包含空白节点
                      //但IE7包含首个注释节点(前面没有元素节点),IE8包含所有注释节点
   对象.childNodes    //获取当前元素节点的所有子节点的集合,包括空白节点
                      //IE7/8不包含空文本节点,但IE7包含首个注释节点(前面没有元素节点),IE8包含所有注释节点

   对象.ownerDocument           //获取该节点的文档根节点,相当与 document

   对象.firstChild              //获得第一个子节点。(包含空白,IE7/8非空白节点,可能是注释节点)
   		对象.firstElementChild       //获得第一个非空白的子节点。(IE7/8不支持)

   对象.lastChild               //获得最后一个子节点(IE7最后一个元素节点,IE8最后一个非空白节点,可能是注释节点)
   		对象.lastElementChild        //获得最后一个非空白的子节点。(IE7/8不支持)

   对象.nextSibling             //获得下一个兄弟节点。(包含空白节点和注释,IE7/8包括注释节点,不包括空白节点)
   		对象.nextElementSibling      //获得下个兄弟节点。(IE7/8不支持)

   对象.previousSibling         //获得上一个兄弟节点。(包含空白节点和注释。IE7/8包括注释节点,不包括空白节点)
  		 对象.previousElementSibling  //获得上一个兄弟节点。(IE7/8不支持)
   
   nodeName:返回节点名字
   nodeValue:返回节点值 (针对文本节点)

如何获取属性节点:
   对象.attributes   //获得所有属性节点,返回一个数组
//body
	<ul>
	  <li>one</li>
	  <li>two</li>
	  <li>123</li>
	  <li>three</li>
	</ul>
	<input type="text" id="ipt" value="10">
//js
  //document 表示文档本身
  console.log(document);    //#document
  var first = document.firstChild;
  console.log(first);   
  var last = document.lastChild;
  console.log(last); 
  //获取body节点
  var bodyObj = last.lastChild;
  console.log(bodyObj);   //<body>...</body>

  //获取ul节点
  var ulObj = bodyObj.firstChild;
  console.log(ulObj);   //#text,会获取空白节点
  var ulObj1 = bodyObj.firstElementChild;
  console.log(ulObj1);   //<ul>...</ul>

  //获取ul节点下的第一个li
  var liObj = ulObj1.firstElementChild;
  console.log(liObj);   //<li>one</li>

  //获取ul节点下的第二个li
  var liObj2 = liObj.nextElementSibling;
  console.log(liObj2);    //<li>two</li>

  //获取ul节点下的第三个li
  var liObj3 = liObj.nextElementSibling.nextElementSibling;
  console.log(liObj3);    //<li>123</li>
    // 或者
  var liObj3_1 = ulObj1.lastElementChild.previousElementSibling;
  console.log(liObj3_1);    //<li>123</li>

  //获取ul节点下的最后一个li
  var liObj4 = ulObj1.lastElementChild;
  console.log(liObj4);    //<li>three</li>

  //获取节点名称
  var nameObj = document.body.nodeName;
  console.log(nameObj);   //BODY
  var nameObj1 = ulObj1.nodeName;
  console.log(nameObj1);  //UL

  //获取文本节点
  var textObj = liObj.firstChild;
  console.log(textObj);   //"one"

  //获取节点值
  var liValue = textObj.nodeValue;
  console.log(liValue);   //one

  //获取父节点
  var fuObj = liObj.parentNode;
  console.log(fuObj);   //<ul>...</ul>

  //获取子节点
  var ziObj = ulObj1.children;
  console.log(ziObj);   //不包含空白节点,[li,li,li,li]
  var ziObj1 = ulObj1.childNodes;
  console.log(ziObj1);  //包含空白节点,[text, li, text, li, text, li, text, li, text]

  //获取文档根节点,相当一document
  var root = liObj.ownerDocument;
  console.log(root);  //#document
  var root1 = ulObj1.ownerDocument;
  console.log(root1);   //#documnet

  //获取属性节点
  var ulAtr = document.getElementById("ipt");
  var atr = ulAtr.attributes;
  console.log(atr)

四、DOM的增 / 删 / 改 / 查

节点创建
    元素节点:document.createElement(tag标签名称);
    文本节点:document.createTextNode(文本内容);
    属性设置:node.setAttribute(名称,值);

节点追加(插入节点)
    父节点.appendChild(子节点);   		 // 向父节点添加最后一个子节点
    父节点.insertBefore(newnode,oldnode);  // 将newnode放到oldnode的前边

节点删除
    父节点.removeChild(子节点);		//删除父节点下的某个子节点
    元素.remove();		//直接删除当前元素

节点查询:选择器

增 / 删 / 改 / 查:

//body
<span>span-span</span>
<ul id="list">
 <li>link1</li>
 <li>link2</li>
 <li>link3</li>
</ul>
//js
 var spanObj = document.getElementsByTagName("span")[0];
 var list = document.getElementById("list");
 //增
     var crtDiv = document.createElement("div");
     var divText = document.createTextNode("div-div");
   
     var crtLi = document.createElement("li");
     var liText = document.createTextNode("link4");
   
     var crtbfLI = document.createElement("p");
     var libfText = document.createTextNode("p标签");
   
     //将文本放到div中,并将div作为父元素的最后一个子节点(默认)
     crtDiv.appendChild(divText);
     document.body.appendChild(crtDiv);
     console.log(document.body.lastElementChild)		//见图1
   
     //将文本放在li中,并作为ul的最后一个子元素
     crtLi.appendChild(liText);
     list.appendChild(crtLi);
   		//为link4增加一个className
        crtLi.className = "li4";
     console.log(document.body.firstElementChild.nextElementSibling);	//见图2
     
     //将p标签插入到ul前
     crtbfLI.appendChild(libfText);
     document.body.insertBefore(crtbfLI,list);
     console.log(document.body);	//见图3

 //删
     //删除div标签
     document.body.removeChild(crtDiv);
     console.log(document.body);	//见图4

     //删除ul标签
     list.remove();
     console.log(document.body)		//见图5
    
//改
	spanObj.innerHTML = "修改后的span标签";
   	console.log(spanObj);			//<span>修改后的span标签</span>
   	//或者
   	spanObj.outerHTML = "<span>" + spanObj.innerHTML + "</span>"

//查
    console.log(document.body.firstElementChild);	//<span>修改后的span标签</span>

DOM的增
DOM的删DOM的删
补充:

  • css DOM:
    • color:red;
      • obj.style.color = ‘red’;
      • obj.style.background = ‘red url()’
      • obj.style.fontSize = ;
      • obj.style.width = “400px”;

上面虽然可以解决部分问题,但是对应非行内样式来说,会出现一些小问题,如下:

//style
.test{height:200px;}
//body
<div style="width:200px" class="test" id="id">非行内样式的获取</div>
//js
var obj = document.getElementById("id");
console.log(obj.style.height);    	//显示为空
console.log(getComputedStyle(obj).height);  	//200px,用于非ie浏览器
// console.log(obj.currentStyle["height"]);    	//用于ie浏览器

因此我们可以封装一个函数来兼容它:

//获取非行内样式(兼容问题)
  function getStyle(obj,attr){     //获取非行间样式,obj是对象,attr是值
      if(obj.currentStyle){                //针对ie获取非行间样式
          return obj.currentStyle[attr];
      }else{
      	//false表示不是获取obj的伪类,true表示获取obj的伪类
          return getComputedStyle(obj,false)[attr];   //针对非ie
      };
  };

五、浏览器尺寸

Method描述
offsetParent获取元素的最近的具有定位属性(absolute或者relative)的父级元素。如果都没有则返回body
offsetLeft表示元素的左外边框至父级元素(offsetParent)的左内边框之间的像素距离
offsetTop表示元素的上外边框至父级元素(offsetParent)的上内边框之间的像素距离
scrollLeft / scrollTop滚动条最顶端和窗口中可见内容的最顶端之间的距离
clientWidth / clientHeight元素视窗宽度/高度
offsetWidth / offsetHeight元素实际宽度/高度

在这里插入图片描述

clientWidth = width+左右padding
clientHeight = height + 上下padding

offsetWidth / offsetHeight:元素实际宽度/高度
offsetWidth = width + 左右padding + 左右boder
offsetHeiht = height + 上下padding + 上下boder
offsetLeft = margin + position

scrollHeight = height + padding + scroll

// 浏览器尺寸
//style
    *{margin:0;}
    #box{width: 500px;height: 500px;border:2px solid #00f;position: relative;left: 100px;top: 200px;padding:10px 5px;}
    #box1{width: 100px;height: 100px;border: 2px solid #000;position:absolute;left: 150px;top:250px;}

//body
	<div id="box">
	  <div id="box1"></div>
	</div>
//js
	var boxObj = document.querySelector("#box");
	var box1Obj = document.querySelector("#box1");
	
	//获取最近的具有定位属性的父级元素,若都没有则返回body
	console.log(boxObj.offsetParent);
	console.log(box1Obj.offsetParent);
	
	//元素左外边框至父级元素左内边框的距离
	console.log(boxObj.offsetLeft);   //100
	console.log(box1Obj.offsetLeft);    //150
	
	//元素上外边框至父级元素上内边框的距离
	console.log(boxObj.offsetTop);    //200
	console.log(box1Obj.offsetTop);   //250
	box1Obj.style.top = "100px";
	console.log(box1Obj.offsetTop);   //100
	
	//元素视窗宽度/高度
	console.log(boxObj.clientWidth);    //510
	console.log(boxObj.clientHeight);   //520
	
	console.log(box1Obj.clientWidth);   //100
	console.log(box1Obj.clientHeight);    //100
	
	//元素实际宽度/高度
	console.log(boxObj.offsetWidth);    //514
	console.log(boxObj.offsetHeight);   //524
	console.log(box1Obj.offsetWidth);   //104
	console.log(box1Obj.offsetHeight);    //104
	

在这里插入图片描述
scrollLeft / scrollTop | 滚动条最顶端和窗口中可见内容的最顶端之间的距离

//body
<div id="out" style="height: 200px;width: 200px;border: 5px solid #000;padding: 50px;overflow: auto;">
	<div id="inn" style="height: 400px;width:400px;border: 5px solid blue;">111</div>
</div>
//js
var out = document.querySelector("#out");
out.scrollLeft = 100;
out.scrollTop = 100;
console.log(out.scrollTop);		//100
console.log(out.scrollLeft);	//100	
console.log(out.scrollHeight);		//510
console.log(out.scrollWidth);		//460

六、案例

1.模拟tab切换页面

//css
*{margin: 0;padding: 0;list-style: none;}
.count{width: 600px;height: 400px;margin:50px auto;border: solid 1px black;}
.count ul{height: 72px;}
.count ul li{width: 199px;height:72px;font: 24px/3 "";float: left;text-align: center;border-bottom: solid 1px black;border-right: solid 1px black;}
.msg div{height: 328px;color: #fff;font:40px/300px "微软雅黑";display: none;text-align: center;}

.msg div:nth-child(1){background: green;}
.msg div:nth-child(2){background: red;}
.msg div:nth-child(3){background: blue;}

.count li.active{background: #ccc;}
.count div.active{display: block;}

//body
<div class="count">
  <ul>
    <li class="active">资源1</li>
    <li>资源2</li>
    <li>资源3</li>
  </ul>
  <div class="msg">
    <div class="active">msg1</div>
    <div>msg2</div>
    <div>msg3</div>
  </div>
</div>
//js
var ali = document.querySelector("ul").children;
var adiv = document.querySelector(".msg").children;

//遍历li
for(var i = 0;i<ali.length;i++){
  ali[i].index = i;
  ali[i].onclick = function(){
    //遍历div
    for(var j = 0;j<adiv.length;j++){
      ali[j].className = "";
			adiv[j].className = "";
    }
    //点中的li的className设为active
    this.className = "active";		
    //点中的li对应的div的className设为active	
		adiv[this.index].className = "active"
  }
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值