1、什么是DOM
定义:DOM是Document object model的简称,是一套专门用来操作html元素对象的方案
使用场景:只要是需要操纵网页中的元素对象的时候都需要使用DOM
DOM标准:DOM标准是有W3C组织制定的,几乎全球所有的浏览器都100%兼容DOM标准
作用:增删改查或者时间绑定
2、DOM树结构
DOM树结构指的是在html中标签的包含关系,是一种层叠的树形结构,类似在电脑系统中的文件夹系统
定义:内存中专门用于存储一个网页中的所有内容的树形结构
作用:因为html中元素结构的复杂性,使用树形结构能清晰的表达中对象的结构关系以及文档结构
文档模型:
树形结构怎么实现:
- 网页文档加载的时候会先建立一个document对象,这是DOM的根结构
- 浏览器扫描网页文件中的内容,然后对扫描的部分在document中建立对应的节点元素,然后添加到DOM树形结构中,然后存储对应的内容
- DOM树上保存元素内容的对象可以称为节点元素
3、查询节点元素的方式
获取元素节点对象:
通过指定节点元素id获取对象:
使用方式: var 变量名 = document.getElementById('元素的id名');
作用:在这个页面中查找匹配的id的元素的节点对象,因为id具有唯一性,返回的是单个节点对象
var s = document.getElementById('id')
通过指定节点元素class获取对象:
使用方式:var 变量名 = docunemt.getE;ementsByClassName('类名')
作用:在页面中匹配对应的标签名的元素节点对象,因为在页面中使用标签重复过多,顾返回的是节点对象的数组
var s = document.getElementsByTagName('li')
通过指定节点元素标签名获取对象:
使用方式:var 变量名 = document.getElementsByTagName('标签名')
作用:在页面中查找匹配的类的元素的节点对象,因为类名在前端中不具有唯一属性,所以返回的是一个对象的引用数组
var s = document.getElementsByClassName('person')
通过document.querySelector()方式获取对象:
使用方式:var 变量名 = 任意父元素.querySelector('任意选择器')
作用:匹配对应选择器的元素节点对象,注意使用该方法只会选择一个对象,查询的所有复合条件的第一个对象
var s = document.querySelector("#demo");
通过document.querySelectorAll()方式获取对象:
使用方式:var 变量名 = 任意父元素.querySelectorAll('任意选择器')
作用:匹配对应选择器的所有元素节点对象的数组
var s = document.querySelector("p");
方式一:使用节点对象名直接获取节点元素
- document:对应的文档DOM结构的根节点,使用这个选中DOM元素,也就是选中整个文档
- document.documentElement:指的是<html>元素
- document.body:指的是<body>元素
- document.head:指的是<head>元素
方式二:通过节点关系查找
父子关系:父子关系指的是元素之间的包含关系
获取父元素节点对象:
父级节点对象=元素.parentNode
注意只会返回一个对象,就是上级父节点对象
获取所有子元素节点对象:
arrs = 元素.childNodes
返回值:(直接)子集节点对象们
返回一个类数组对象,其中包含当前元素下的所有直接子元素对象
获取第一个直接子元素节点对象:
var jiedian = 元素.firstChild
返回值:第一个(直接)孩子
返回当前元素下第一个直接子元素对象
获取最后以一个直接子元素节点对象:
var jiedian = 元素.lastChild
返回值:最后一个(直接)孩子
返回当前元素下最后一个直接子元素对象
兄弟关系:兄弟关系指的是元素中间的并列关系
获取前面一个兄弟元素节点对象:
var 节点 = 元素.previousSibling
返回值:前一个兄弟
获取后面一个兄弟元素节点对象:
var 节点 = 元素.nextSibling
返回:后一个兄弟
4、元素树
定义:仅包含元素节点的树结构,不包含内容节点树
优点:不包含看不见的空字符节点对象,不会干扰查找
使用场景:今后只要按节点间关系查找周围附近元素时,都首选元素树
4.1、使用方法:
父子关系:
- 获取父元素
- 使用方法:元素.parentElement(注定只返回当前元素的一个父节点对象)
//验证span的父元素是不是body
console.log(span.parentElement==document.body);//true
- 获取子元素
- 使用方法:元素.children(返回一个类数组对象,其中包含当前元素下的所有直接子元素对象)
//想获得body下所有直接子元素
var childNodes=document.body.children;
console.log(childNodes);
- 获取第一个子元素
- 使用方法:元素.firstElementChild(返回当前元素下第一个直接子元素对象)
//获得body下第一个直接子元素span
var span=document.body.firstElementChild;
- 获取最后一个子元素
- 使用方法:元素.lastElementChild(返回当前元素下最后一个直接子元素对象)
//获得body下最后一个直接子元素span
var span=document.body.lastElementChild;
- 获取指定中间的子元素
- 使用方法:document.body.children[1] (返回一个类数组对象中指定index对象)
//想获得body下第二个直接子元素h1
var h1=document.body.children[1];
兄弟关系:
- 获取前一个兄弟元素
- 使用方法:元素.previousElementSibling(前一个元素兄弟)
//验证h1的前一个兄弟是不是span
console.log(h1.previousElementSibling==span);//true
- 获取后一个兄弟元素
- 使用方法:元素.nextElementSibling(后一个元素兄弟)
//验证span的下一个兄弟元素是不是h1
console.log(span.nextElementSibling==h1);//true
扩展:
输出DOM关系结构
console.log(document);//输出DOM关系结构
输出节点对象自身的存储结构:
console.dir(document);//输出对象自身的存储结构(属性和方法)
5、事件绑定方法
方式一:在HTML标签中都有事件属性,使用事件属性绑定函数
注意:一般不会使用这种方式,因为这种方式固定了事件绑定的位置,必须是在标签内部;这种情况下每当项目文件过大,且时间众多的时候,使用方式一绑定事件,在后期维护的时候查找事件就是一件非常可怕的事情
方式二:在js中内置了一系列绑定事件,都是以on开头加上事件名的事件绑定函数
使用方法:元素对象.on事件名=function(){ ... }
6、DOM使用步骤
查找触发事件的元素
绑定事件处理函数
查找需要修改的元素对象
修改元素对象
扩展:
问题:在事件处理函数中使用循环变量,无法获得当前正在点击的元素,始终只能获得最后一个元素。
原因:今后,在事件处理函数中最忌讳使用外部变量!因为事件的触发和程序的执行是有时间差的!在这段时间差中,外部变量很可能早就被改成别的值了!尤其是循环变量更不可靠。因为循环变量天生即使随循环不断变化的。
解决:今后,只要在事件处理函数中,想获得当前正在点击的元素对象,都要用this
事件处理函数中的this都指向当前正在触发事件的元素对象本身。
//1.1 先通过id名data找到table
var table=document.getElementById("data");
//1.2 再在table范围内查找所有button元素
var buttons=table.getElementsByTagName("button");
//1.3 绑定事件处理函数
for(var btn of buttons)
{
console.dir(btn);
// 当单击时就自动执行...
btn.onclick=function(){
this.innerHTML="❀";
}
}