Js中的Dom
一、Dom的相关概念介绍
1.API:应用程序编程接口,目的是提供应用程序与开发人员基于某软件或硬件得以访问
一组例程的能力。
2.Web API:浏览器提供的一套操作浏览器功能和页面元素的API(BOM DOM),主要针对浏览器交互效果。
3.DOM:文档对象模型,处理可扩展标记语言(HTML/XHTML)的标准编程接口。通过DOM接口可以改变网页的内容、结构、样式。
二、Dom获取元素
2.1 根据ID获取
- 根据ID获取的函数为:document.getElementById()
- 语法格式
<body>
<div id="time">
2020-04-26
</div>
<Script>
var timer = document.getElementById('time');
</script>
</body>
2.2 根据标签名获取
- 根据标签名获取的方法:getElementsByTagName() 返回值为带有标签名的对象集合
- 语法格式如下
<body>
<ul>
<li>知否知否,应是等你好久1</li>
<li>知否知否,应是等你好久2</li>
<li>知否知否,应是等你好久3</li>
<li>知否知否,应是等你好久4</li>
</ul>
<ol id="ol">
<li>生僻字</li>
<li>生僻字</li>
<li>生僻字</li>
<li>生僻字</li>
</ol>
</body>
<script>
// 1.返回的是 获取过来元素对象的集合 以伪数组的形式存储的
var lis = document.getElementsByTagName('li');
// 2.如果页面中只有一个li 返回的还是伪数组的形式 ,如果页面中没有这个元素 返回的是空的伪数组的形式
// 3. element.getElementsByTagName('标签名'); 父元素必须是指定的单个元素,不能是伪数组形式(比较繁琐 可以设置id获取)
var ol = document.getElementById('ol');
console.log(ol.getElementsByTagName('li'));
</script>
2.3 HTML5新增的获取方法
- document.getElementsByClassName(‘类名’)
// 1. getElementsByClassName 根据类名获得某些元素集合
var boxs = document.getElementsByClassName('box');
- document.querySelector(‘选择器’)
语法格式 | 解释 |
---|---|
var firstBox = document.querySelector(’.box’); | 获取class名为box的第一个元素 |
var nav = document.querySelector(’#nav’); | 获取id为nav的第一个元素 |
var li = document.querySelector(‘li’); | 获取li标签的第一个元素 |
var allBox = document.querySelectorAll(’.box’); | 获取class为box的所有元素 |
2.4 特殊元素获取
- 获取body元素
var bodyEle = document.body;
- 获取html元素
var htmlEle = document.documentElement;
三、操作元素(Dom核心)
3.1 事件基础
- JS使我们能够创建动态页面,而事件是可以被js检测到的行为,及触发-响应机制。
- 事件的三要素:事件源、事件类型、事件处理程序
//(1) 事件源:事件被触发的对象、谁、按钮
var btn = document.getElementById('btn');
//(2) 事件类型:如何触发、什么事件、比如鼠标点击(onclick) 还是鼠标经过 还是键盘按下
//(3) 事件处理程序:通过一个函数赋值的方式完成
btn.onclick = function() {
alert('点秋香');
}
- 3.1.3 常见的鼠标事件
鼠标事件 | 触发事件 |
---|---|
onclick | 鼠标点击左键触发 |
onmouseover | 鼠标经过触发 |
onmouseout | 鼠标离开触发 |
onfocus | 获取鼠标焦点触发 |
onblur | 失去鼠标移动触发 |
onmousemove | 鼠标移动触发 |
onmousedown | 鼠标按下触发 |
onmouseup | 鼠标谈起触发 |
3.2 操作元素的内容:innerText&innerHTML
- innerText和innerHTML都是获取document对象文本内容
- innerText与innerHTML的区别
- innerText不识别HTML标签,里面的HTML标签会直接显示,innerHTML可识别
- 这两个属性均是可读写的,可以获取到元素里面的内容,但是innerText会直接去掉元素内容里面的html标签,innerHTML全保留。
3.3 操作常见元素属性
- 常见的元素属性有:src、href、id、alt、title
- 常见的表单属性有:
- 常见的元素样式属性有:element.style/element.className
3.4 排它思想
- 概念:如果有同一组元素,我们想要某一个元素实现某种样式,需要用到循环的排它思想算法:所有元素的样式全部清除,给当前元素设置样式。(排除他人,留下自己)
- 案例分析:点击按钮后 按钮变色
//1.获取所有按钮元素
var btns = document.getElementsByTagName('button');
for(var i = 0; i < btns.length; i++){
btns[i].onclick = function(){
//先把所有的按钮的背景颜色去掉
for(var i = 0;i < btns.length; i++){
btns[i].style.backgroundColor = '';
}
//再让被点击的元素背景色为粉红色
this.style.backgroundColor = 'pink';
}
3.5 自定义属性
- 自定义属性操作
- 获取内置的属性值:element.属性
- 获取自定义属性值:element.getAttribute(‘属性’)
<div id="demo" index="1"></div>
<script>
var div = document.querySelector('div');
//1.获取元素的属性值
//(1)element.属性
console.log(div.id); //demo
//(2)element.getAttribute('属性')
console.log(div.getAttribute('index')); //1
- 设置属性值
- 设置内置属性值:element.属性 = ‘值’
- 设置自定义属性值:element.setAttribute(‘属性’)
div.id = 'test';
div.setAttribute('index', 2); //2
- 移除属性:element.removeAttribute(‘属性’)
div.removeAttribute('index');
- H5自定义属性
- H5规定以data-开头的属性名为自定义属性
- H5新增获取自定义属性的方法:element.dataset.index/element.dataset[ ’ index’],dataset是一个集合,里面存放了所有以data开头的自定义属性
<div getTime="20" data-index="2" data-list-name="andy"></div>
<script>
console.log(div.dataset);
console.log(div.dataset.index);
console.log(div.dataset['index']);
</script>
3.6 节点操作
3.6.1 节点的基本概念
- 概念:网页中所有的元素都是节点,利用节点层级关系,获取元素,逻辑性更强。利用dom树可以把节点划分为两种不同的层级关系,常见的是父子兄层级关系。
- 父级节点:node.parentNode
// 1. 父节点 parentNode
var erweima = document.querySelector('.erweima');
// 得到的是离元素最近的父级节点(亲爸爸) 如果找不到父节点就返回为 null
console.log(erweima.parentNode);
- 子节点:parentNode.childNodes(集合)
var ul = document.querySelector('ul'); //假设ul里面有四个小li
var lis = ul.querySelectorAll('li');
// 2. 子节点 childNodes 所有的子节点 包含 元素节点 文本节点(换行)等等
console.log(ul.childNodes); //9个
console.log(ul.childNodes[0].nodeType); //文本节点的nodeType是3
console.log(ul.childNodes[1].nodeType); //元素节点的nodeType是1
// 2.2 children 获取所有的子元素节点也是我们实际开发常用的
console.log(ul.children); //4个
- 兄弟节点:node.nextSibling
var div = document.querySelector('div');
// 3.nextSibling 下一个兄弟节点 包含元素节点或文本节点等等
console.log(div.nextSibling); //text
console.log(div.previousSibling); //text
// 3.2 nextElementSibling 得到下一个兄弟元素节点
console.log(div.nextElementSibling); //span
console.log(div.previousElementSibling); //得到上一个兄弟结点 none
3.6.2 节点的相关操作
- 获取第一个和最后一个子节点的操作
- parentNode.firstChild、parentNode.lastChild:包含文本节点、元素节点
- parentNode.firstElementChild、parentNode.lastElementChild:获取元素节点,有兼容性问题,IE9上才支持。
- 创建或添加节点:
- 我们想要页面添加一个新的元素的操作:创建元素 → 添加元素
- document.createElement(‘tagName’):创建节点的元素节点
var li = document.createElement('li');
- node.appendChild(child): node 父级 child子级 即给该父级节点添加一个子节点
var ul = document.querySelector('ul');
ul.appendChild(li);
- node.insertBefore(child,指定元素):在指定位置添加节点
var lili = document.createElement('li');
ul.insertBefore(lili, ul.children[0]);
- 删除节点操作:node.removeChild(child)
ul.removeChild(ul.children[0]);
- 复制克隆节点:node.cloneNode()
- node.cloneNode(); 括号为空或者里面是false 浅拷贝 只复制标签不复制里面的内容
- node.cloneNode(true); 括号为true 深拷贝 复制标签并复制里面的内容
3.6.3 三种动态创建元素的区别
- document.write( ) :直接将内容写入页面的内容流,但是文档流执行完毕,会导致页面重绘(生成新页面,且新页面中只含write里内容)
- element.innerHTML:创建多个元素时候效率更高(不用拼接字符串,采取数字方式拼接),结构稍复杂
- document.createElement( ):效率稍微低一点点,但是结构更清晰。
四、DOM总结
- 对于dom操作,我们主要针对元素的操作,主要有创建、增删改查、属性操作、事件操作
- 创建:document.write、innerHTML、createElement
- 增:appendChild、insetBefore
- 删除:removeChild
- 改:主要是修改dom的元素属性、内容、属性值等
- 查:主要获取查询的dom元素
- DOM提供的API方法:getElementById、getElementsByTagName
- H5提供的新方法:querySelector、querySelectedtorAll
- 利用节点获取元素:parentNode、children、previousElementSibling、nextElementSibling
- 属性操作:主要针对自定义属性:setAttribute、getAttribute、removeAttribute
- 事件操作:给元素注册事件,采取事件源.事件类型 = 事件处理程序
- 注册事件:给元素添加事件,称为注册事件/绑定事件。主要有两种方式
- 传统注册方式(注册事件唯一性):同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数会覆盖前面注册的处理函数。
- 方法监听注册方式:addEventListener(),同一个元素同一个事件可以注册多个监听器,按注册事件依次执行。
- 语法格式为: eventTarget.addEventListener(type, listener[, useCapture]);
- type:事件类型字符串 比如click、mouseover;listener:事件处理函数,事件发生时候调用,useCapture:可选参数,是一个布尔值,默认是false。
- 删除事件
- 传统删除方式:eventTarget.onclick = null;
- 方法监听注册方式:eventTarget.removeEventListener(type,listener,useCapture)
- Dom事件流
- 事件流是描述从页面中接受事件的顺序,事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程叫做dom事件流。
- 主要分成三个阶段:捕获阶段、当前目标阶段、冒泡阶段。
- JS代码只能够执行捕获或者冒泡的其中一个阶段
- onclick和attachEvent只能到冒泡阶段,addEventListener(type, listener[, useCapture])第三个参数如果是true,表示事件在捕获阶段调用事件处理程序,如果是false/空,表示在事件冒泡阶段调用事件处理程序。
- 实际开发中更关注事件的冒泡
- onblur、onfocus、onmouseenter、onmouseleave是没有冒泡的
- 事件对象
- 概念:eventTarget.onclick = function(event){}中的event就是事件对象,还可以写成e/evt,event表示事件的状态,有很多的属性和方法,是一个形参,不需要传递实参,由系统自己创建,ie6~8存在兼容问题。
- 事件对象常用的属性和方法
事件对象属性方法 | 说明 |
---|---|
e,target | 返回触发事件的对象 |
e.srcElement | 返回触发事件的对象 |
e.type | 返回事件的类型 |
e.cancelBubble | 该属性阻止事件冒泡 |
e.returnValue | 该属性阻止默认事件 |
e.preventDefault() | 该方法阻止默认事件 |
e.stopPropagation() | 阻止冒泡 |