DOM对象
DOM对象
一、什么是DOM对象
Document Object Model(文档对象模型)
DOM描绘了一个层次化的节点树,允许开发人员添加、移除和修改页面的某一部分。
HTML DOM 定义了访问和操作HTML文档的标准方法。
要改变页面的某个东西,JavaScript 就需要获得对 HTML 文档中所有元素进行访问的入口。这个入口,连同对 HTML 元素进行添加、移动、改变或移除的方法和属性,都是通过文档对象模型来获得的(DOM)。
我们可以通过JavaScript操作DOM,可以对节点实现增删改查操作,可以动态添加标签,属性等。
二、DOM节点
HTML 文档中的每个成分都是一个节点。文本、注释、文档、属性都是节点。
(1)节点类型
DOM 是这样规定的:
整个文档是一个文档节点
每个 HTML 标签是一个元素节点
包含在 HTML 元素中的文本是文本节点
每一个 HTML 属性是一个属性节点
注释属于注释节点
常见的节点类型:
document
===页面中最大的节点,它不是元素节点
===作为承载容器的节点,叫做根节点
html
===页面中最大的元素节点,叫做根元素节点
head/body/div/ul......
===普通的元素节点
===都是元素节点
文本节点
===一段文本,包含换行和空格
属性节点
===是元素标签上的属性
注释节点
===就是一段只是
===这个节点在页面上不会显示
(2)节点层次关系-节点彼此都有等级关系。
HTML 文档中的所有节点组成了一个文档树(或节点树)。HTML 文档中的每个元素、属性、文本等都代表着树中的一个节点。树起始于文档节点,并由此继续伸出枝条,直到处于这棵树最低级别的所有文本节点为止。
<head> 和 <body> 的父节点是 <html> 节点,文本节点 "Hello world!" 的父节点是 <p> 节点。
<head> 节点有一个子节点:<title> 节点。<title> 节点也有一个子节点:文本节点 "DOM Tutorial"。
当节点分享同一个父节点时,它们就是同辈(同级节点)。比方说,<h1> 和 <p>是同辈,因为它们的父节点均是 <body> 节点。
节点也可以拥有后代,后代指某个节点的所有子节点,或者这些子节点的子节点。
节点也可以拥有先辈。先辈是某个节点的父节点,或者父节点的父节点,以此类推。比方说,所有的文本节点都可把 <html> 节点作为先辈节点。
(3)节点属性
每个节点都拥有包含着关于节点某些信息的属性。这些属性是:
nodeName(节点名称)
元素节点的 nodeName 是标签名称
文本节点的 nodeName 永远是 #text
注释节点的 nodeName 永远是 #comment
nodeValue(节点值)
文本节点,nodeValue 属性包含文本。
元素节点nodeValue不可用
注释节点nodeValue包括注释内容
nodeType(节点类型)
元素----------------1
属性----------------2
文本----------------3
注释----------------8
文档----------------9
三、获取DOM元素
非常规标签获取
- document.body //body
- document.head //head
- document.documentElement //HTML
- document //整个文档
- document.title //title
- document.URL //location.href
- document.domain //域名
常规标签获取
- document.getElementById() //通过ID获取Dom元素
- document.getElementsByTagName() //通过标签名获取Dom元素
- document.getElementsByName() //通过namei属性获取Dom元素
- document.getElementsByClassName() //通过类名获取Dom元素
- document.querySelector() //根据选择器获取单个标签
- document.querySelectorAll() //根据选择器获取多个标签的列表
注:
1.document.getElementsByTagName(),document.getElementsByClassName()得到的是HTMLCollection列表;
document.getElementsByName(),document.querySelectorAll()得到的是NodeList列表。
2.除了通过ID获取和通过name属性获取的方式外,其他的方式都可以通过父元素获取到子元素
div.getElementsByClassName(“div1”);
div.getElementsByTagName(“div1”);
div.querySelector(".div1");
div.querySelectorAll(".div1");
3.querySlector()与querySlectorAll()两个方法在ie的低版本不支持
四、Dom节点遍历
通过节点之间的关系获取相关节点
1、获取节点(各种节点都有可能)
节点.childNodes :获取元素的所有子节点
节点.firstChild :获取元素的第一个子节点
节点.lastChild :获取元素的最后一个子节点
节点.parentNode :获取元素的父节点(常用)
节点.nextSibling :获取元素的下一个同级节点
节点.previousSibling :获取元素的上一个同级节点
2、获取元素节点(标签)
节点.children :获取元素的所有子元素节点(常用)
节点.firstElementChild :获取元素的第一个子元素节点
节点.lastElementChild :获取元素的最后一个子元素节点
节点.parentElement :获取元素的父元素节点
节点.nextElementSibling :获取元素的下一个同级元素节点
节点.previousElementSibling :获取元素的上一个同级元素节点
3、获取属性节点
语法: 元素节点.attributes
可以通过下标获取对应的属性
例如:div.sttributes[0]
五、操作节点
1. 创建节点
document.createElement(“标签名”) //创建新元素
document.createTextNode("文本内容 ") //创建文本节点
document.createDocumentFragment() //创建文档碎片容器
2.插入节点
父节点.appendChild(要插入的节点) //插入节点到父元素的尾部
父节点.insertBefore(要插入的节点,要插入到哪个节点前) //在元素前面插入
注:如果第二个参数为null或者undefined时,那意思就是插入到节点的末尾
3.复制节点
node.cloneNode(false) //浅复制,复制原标签的所有属性和样式,不包含内容和后代元素,默认是false
node.cloneNode(true) //深复制,可以将内容和后代一起复制
4.删除节点
要删除的节点.remove()
父节点.removeChild(要删除的节点) //在父节点中删除元素
5.替换节点
父节点.replaceChild(新节点,被替换的节点)
六、操作元素的文本内容
- innerHTML
是一个读写属性
读语法:元素.innerHTML,会得到元素里所有的超文本结构以字符串的形式返回
写语法:元素.innerHTML=“你要输入的文本”。能解析文本中的HTML标签 - innerText
是一个读写属性
读语法:元素.innerText,会得到元素里所有的文本结构以字符串的形式返回
写语法:元素.innerText=“你要写入的内容”。不能解析内容中的HTML标签
3.value
是一个读写属性,专门用来读取表单元素的内容
读语法:input.value,得到表单元素的value值
写语法:input,value=" "
七、DOM属性
操作元素的原生属性
- 原生属性:元素自带的属性,如:src,type,id等
- 读语法:元素.属性名
- 写语法:元素.属性名=" "
img.src=“pic.jpg”;
input.type=“text”
div.id=“div1”
操作元素的自定义属性
- 自定义属性:元素本身没有的属性,是我们自己定义的属性,在标签上没有表现形式,只用来记录一些信息
- 设置元素的自定义属性
元素.setAttribute(“属性名”,“属性值”) - 获取元素的自定义属性
元素.getAttribute(“属性名”) - 删除元素的自定义属性
元素.removeArribute(“属性名”)
操作元素的类名
- 在js中class是一个关键字,所以操作类名不能用class,使用className属性
- 读语法:元素.className
得到的是整体的class属性值,以字符串的形式返回 - 写语法:元素.className=“类名”
注意
- 自定义属性的命名和值必须使用小写和横线连接
<div id="div1" class="divs div1" name="abc" data-main="ac"></div>
- 标签属性和DOM的对象属性区别
先有的标签,才可以渲染对象调用,DOM的对象属性和标签属性不一定相同,也不一定能互相获取,有些标签默认属性可以通过DOM属性调用,而DOM的自定义属性和标签的自定义属性是完全不能相互调用的。可以通过setArribute方法通过DOM对象设置标签的属性。
八、DOM样式
给DOM对象设置行内样式
1、语法1:对象属性样式写入
div.style.width=“50px”;
注意:在设置样式时,如果样式属性名由多个词汇组成,去掉-并把后面的字母大写,例如:
div.style.backgroundColor=“red”;
2、语法二:直接行内样式写入
div.style="width:50px;height:50px;background-color:“red;”;
3、注意点:style属性只能给dom对象设置行内样式,也就是直接在标签上添加style样式,不能设置伪类和伪元素的DOM样式。
4、通过document.querySelector()获取到的是NodeList,他有一个forEach方法,可以通过该方法给每个dom对象添加样式
var divs=document.querySelector(“div”);
divs.forEach(function(item){
item.style.width=“50px”;
})
5、使用Object.assign()方法添加DOM样式
Object.assign(div.style,{
width: “50px”,
height: “50px”,
backgroundColor: red
})
6、获取计算后的DOM样式
getComputedStyle(“div”)
不兼容IE8一下的版本,IE8以下的方法:
div.currentStyle
通过try,catch语句解决兼容问题
var style
try{
style=getComputedStyle(div1);
}catch(e){
style=div1.currentStyle;
}
console.log(style.width,style.left);
九、CSS样式
可以通过document.styleSheets获取和添加CSS样式
var styleSheet=document.styleSheets[document.styleSheets.length-1];
// IE都支持
styleSheet.addRule(".div1","width:50px;height:50px;background-color:red",0);
styleSheet.addRule(".div1:hover","background-color:blue",1);
// IE9以上支持
styleSheet.insertRule(".div1 {width:50px;height:50px;background-color:red}",0)
十、DOM对象的常用属性(offset、client)
DOM常用属性必须是已经放在页面中渲染的DOM对象元素
1、元素的宽高 width height
- clientWidth clientHeight 客户宽高,边框以内的所有宽高之和-滚动条宽高
- offsetWidth offsetHeight 偏移宽高,DOM元素在页面中占位的宽高
- scrollWidth scrollHeight 滚动区域宽高
document.body
console.log(document.body.clientWidth,document.body.clientHeight);
console.log(document.body.offsetWidth,document.body.offsetHeight);
console.log(document.body.scrollWidth,document.body.scrollHeight);//scrollWidth是内容的宽度
document.documentElement
console.log(document.documentElement.clientWidth, document.documentElement.clientHeight);//可视区域宽高-滚动条宽高
console.log(document.documentElement.offsetWidth, document.documentElement.offsetHeight);//body的宽高+body的margin
console.log(document.documentElement.scrollWidth, document.documentElement.scrollHeight);//滚动区域的宽高,如果滚动区域的宽高小于可视区域,则为可视区域的宽高
2、元素的位置 left top
- clientLeft clientTop 客户位置,表示边线宽高,一般不使用
- offsetLeft offsetTop 偏移位置,元素左上角的相对位置,如果子元素相对于父元素定位,则是子元素左上角相对父元素的位置
- scrollLeft scrollTop 滚动条的位置,是一个可读可写的属性
浏览器卷去的尺寸
浏览器卷去的高度:
语法1:document.documentElement.scrollTop
语法2:document.body.scrollTop
两种语法有兼容问题,兼容写法:
var scrollTop=document.documentElement.scrollTop || document.body.scrollTop
3、偏移量参考父级
- 偏移量参考父级
== 是指一个元素的偏移量(left/top)是根据谁来计算的
== offsetParent
== 可以获取到元素偏移量的参考元素
4.小练习:回到顶部
var div;
var bool=false;
init();
function init(){
div=document.querySelector('div');
div.addEventListener('click',clickHandler);
document.addEventListener('scroll',scrollHandler);
setInterval(animation,16);
}
function scrollHandler(e){
if(document.documentElement.scrollTop>document.documentElement.clientHeight) div.style.display="block";
else div.style.display="none";
}
function clickHandler(e){
bool=true;
}
function animation(){
if(!bool) return;
document.documentElement.scrollTop-=200;
bool=document.documentElement.scrollTop!==0;
}