一、DOM 事件基础
DOM 文档对象模型(Document Object Model) 是一个接口,处理可扩展标记语言(HTML,XML)
1.获取元素
1.1 根据id获取 getElementById
document.getElementById('xxx') 返回的是一个元素对象 console.dir(xxx) 打印返回的元素对象,更好的查询里面的元素和方法
1.2 根据标签名获取 getElementsByTagName
- document.getElementsByTagName('xxx') 返回的是 获取过来的元素对象的集合,以伪数组的形式存储 如果页面中没有这个元素,返回的是空的伪数组
- element.getElementsByTagName('xxx') 父元素必须是单个对象(必须指明是哪一个元素对象)
1.3 根据类名获取 getElementsByClassName
1.4 根据指定选择器获取
- document.querySelector('.类名 / #id名 / ...') 返回第一个元素对象
- document.querySelectorAll('xxx') 返回所有元素对象集合
1.5 获取特殊元素
- 获取body元素 document.body
- 获取html元素 document.documentElement
2.事件
2.1 事件三要素
-
事件源 事件被触发的对象
-
事件类型 如何触发
-
事件处理程序 用一个函数赋值的方式来实现
2.2 执行事件的步骤
- 获取事件源
- 绑定事件 注册事件
- 添加事件处理程序
3.操作元素
3.1修改元素内容
- element.innerText 不标准,不识别HTML标签,忽略空格和换行
- element.innerHtml W3C标准,识别HTML标签,保留空格和换行
3.1.1 innerText 和innerHtml的区别
3.2修改表单属性
修改表单属性不能用innerHtml,应:input.value = ‘请输入内容’; input.type = ‘password';
3.3 修改样式属性
-
样式比较少,功能简单: this.style.backgroundColor = 'pink'; this.style.width = '300px';
-
通过修改元素的className来更改元素属性
- this.className = '更改的类名' 会直接覆盖掉之前的类名 (在类里设置css样式)
- this.className = '原来的类名 更改的类名' 两者都会保留下来
3.4排他思想
让所有相关元素的相关属性隐藏,然后设置当前元素的属性
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 = 'white';
this.style.backgroundColor = 'pink';
}
}
}
3.5自定义属性的操作
3.5.1 获取属性值
- element.属性 例:div.id 获取内置属性值,即元素本身自带的属性
- element.getAttribute('属性') 获取程序员自定义的属性
3.5.2 设置属性值
- element.属性 = '值' 例:div.className = 'box';
- element.setAttribute('属性', '值') 例:div.setAttribute('class', 'box'); 主要针对于自定义属性 class属性较特殊,使用第一种方法用className,第二种方法用class
3.5.3 移除属性
element.removeAttribute('属性')
3.5.4 H5自定义属性 3
-
H5规定自定义属性名要以data-开头 如:
-
H5获取自定义属性新方法
- element.dataset.属性 (data-后边的属性名) 如:div.dataset.index / div.dataset['index']
- dataset 是一个集合,里边存放了所有以data- 开头的自定义属性
- 如果自定义属性里有多个 - 链接的单词,获取时要采用驼峰命名法 如: data-list-name = 'amy' element.dataset.listName/['listName']
4.节点操作
4.1 节点概述
网页中所有内容都是节点(标签,属性,文本,注释等) 一般地,节点至少有三个属性:nodeType,nodeName,nodeValue
节点可分为:
- 元素节点:nodeType为1
- 属性节点:nodeType为2
- 文本节点:nodeType为3 (包括文字,空格,换行等)
4.2 节点层级
-
父节点:parentNode 得到的是最近的父结点,如果没有则返回null
-
子节点:
- childNodes 得到所有的子节点,包括元素节点,文本节点
- children 得到子元素节点
- firstChild/lastChild 得到第一个/最后一个子节点
- firstElementChild/last... 得到第一个/最后一个子元素节点 IE9以上才支持
- 实际开发中,用children[i]取特定位置的子元素节点
-
兄弟节点:
- nextSibling/previousSibling 得到下一个/上一个兄弟节点
- nextElementSibling/pre... 得到下一个/上一个兄弟元素节点 IE9以上支持
4.3 创建和添加节点
-
创建节点 document.createElement('xx')
-
添加节点
- node.appendChild(child) node是父节点,child是子节点,在后面追加元素
- node.insertBefore(child,指定元素) 在指定元素节点前面添加
4.4 删除节点
node.removeChild(child) node是父结点
4.5 克隆节点
node.cloneNode()
- 括号为空或者里面是false,浅拷贝,只复制标签不复制里面的内容
- 括号里为true,深拷贝,复制标签且复制里面的内容
4.6 三种创建元素方式的区别
- document.write 如果页面加载完毕,再调用这句话会导致页面重绘
- innerHtml 创建多个元素效率更高,(不要采用拼接字符串,而是用数组形式拼接),但结构复杂
- document.creatElement() 创建多个元素效率稍低一点点,但结构清晰
二、DOM 事件高级
1.注册事件
1.1 概述
- 传统注册方式 利用on开头的事件(onclick) 同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数会覆盖前面的处理函数
- 方法监听注册方式 addEventListener( ) IE9之前不支持,同一个元素同一个事件可以注册多个监听器
1.2 addEventListener( )
eventTarget.addEventListener(type,listener[,useCapture])
- type:事件类型字符串,比如click,mouseover,这里不带on,要加引号
- listener:事件处理函数
- useCapture:可选参数,布尔值,默认为false
- 例:btn.addEventListener('click',function(){ alert('你好'); })
2.删除事件
- 传统方式删除事件 例:div.onclick = null;
- removeEventListener() eventTarget.removeEventListener(type,listener[,useCapture])
3.DOM事件流
DOM事件流 即事件传播的顺序 分为三个阶段:
- 捕获阶段
- 当前目标阶段
- 冒泡阶段
addEventListener( ) 第三个参数如果是true,则是捕获阶段;如果是false或省略,则是冒泡阶段 有些事件是没有冒泡阶段的,如:onblur,onfocus,onmouseenter,onmouseleave
4.事件对象
4.1 事件对象概述
- 事件对象写在侦听函数的小括号里面,当作形参来看
- 事件对象是系统自动创建的,不需要我们去传递参数
- 事件对象是事件的一系列相关数据的集合,比如鼠标事件包含了鼠标的信息:鼠标坐标等;键盘事件包含了键盘的信息:判断用户按下了哪个键等
4.2 事件对象常见属性和方法
4.3 事件委托(代理,委派)?
不需要给每个子节点单独设置事件监听器,而是将事件监听器设置在父节点上,利用冒泡原理影响设置每个子节点
4.4 获得鼠标在页面中的坐标
e.clientX/Y 是在可视区内的坐标,不受滚动条影响
5.键盘事件
5.1 常用键盘事件
三个事件的执行顺序 keydown---keypress---keyup
5.2 键盘事件对象
keyCode属性可以得到相应键的ASCII码值,住:keyup和keydown不区分大小写,keypress区分
6.鼠标事件
6.1 鼠标拖拽事件
鼠标拖拽事件由三个事件组成:onmousedown+onmousemove+onmouseup (案例见pc端网页特效1.1.2)
6.2 mouseover 和 mouseenter的区别
- mouseover 鼠标经过元素触发事件,经过它的子元素会再触发
- mouseenter 事件触发一次之后,经过子元素不会再触发
原因:mouseenter不会冒泡,mouseover会。 当鼠标经过元素时会触发事件,经过子元素,子元素得到鼠标经过,但它没有事件,会向上冒泡到父元素,所以父元素会再触发一次事件。
mouseenter搭配mouseleave事件,mouseleave也没有冒泡
三、BOM 浏览器对象模型
1.BOM概述
BOM由一系列对象组成,每个对象都包含很多的属性和方法。BOM的顶级对象是window,BOM包含DOM
2.window对象的常见事件
2.1 窗口加载事件
- window.onload 是窗口(页面)加载事件,当文档内容完全加载完成会触发该事件
- 有了window.onload 就可以把 js 代码放在页面的上方,它的传统注册事件方式只能写一次,如果有多个,会以最后一个window.onload为准
- window.addEventListener没有限制
2.2 调整窗口大小事件
-
window.onresize = function() { }
-
window.addEventListener('resize', function() { })
window.innerWidth:当前窗口大小
2.3 定时器
-
setTimeout
window.setTimeout(调用函数,[延迟的毫秒数])
- window在调用的时候可以省略,延迟时间单位是毫秒,省略为0
- 有多个定时器时,可以给定时器起标识符 var xxx = setTimeout(...)
- 清除定时器:window.clearTimeout(timeoutID) window可省略,括号内是定时器的标识符
-
setInterval
每隔一个延时时间就调用一次函数,一直重复调用。其余与setTimeout相同
3.js执行机制
3.1 同步和异步
- 同步:前一个任务结束才能执行后一个任务,程序执行顺序与任务的排列顺序相同
- 异步:在执行某一个任务时,可以同时进行另一个任务
3.2 执行过程:
- 先执行 执行栈 中的同步任务
- 异步任务(回调函数)放入任务队列中
- 当执行栈中所有的同步任务执行完毕后,系统会按顺序读取任务队列中的异步任务,被读取的异步任务进入执行栈,开始执行
4.location对象
4.1 location对象属性
4.2 location对象方法
5.navigator对象
navigator包含有关浏览器的信息,它有很多属性,其中userAgent可以判断用户在哪个终端打开的页面,并实现跳转
6.history对象
history对象与浏览器历史记录进行交互,它包含用户在浏览器中访问过的url
方法:
- history.back( ) 可以实现后退功能
- history.forward( ) 可以实现前进功能
- history(-1/1/2) 后退1步/前进1步/前进2步
7.本地存储
将数据存储在用户浏览器中
7.1 window.sessionStorage
-
生命周期为关闭浏览器窗口
-
使用:
- sessionStorage.setItem(key,value) 存储数据
- sessionStorage.getItem(key) 获取数据
- sessionStorage.removeItem(key) 移除数据
- sessionStorage.clear() 清除全部数据
7.2 window.localStorage
- 生命周期永久生效,除非手动删除
- 可以多窗口(页面)共享,只要是同一浏览器
- 使用:同sessionStorage一样