1 HTML DOM
1.1 表单相关元素
① form 元素
length form中表单控件的个数
element 返回一个对象,对象中是form里的表单控件
submit() 该方法可提交表单
reset() 该方法可重置表单
② 文本输入框和文本域(input和textarea)
focus() 让元素获取焦点
blur() 让元素失去焦点
select() 选中里面的文本内容
③ select 元素
length 获取或设置下拉选项的数量
options 获取所有下拉选项的集合
value 获取所选下拉选项的value
selectedIndex 获取所选下拉选项的索引
add() 添加一个下拉选项,参数是option元素对象
remove() 删除指定的下拉选项,参数是索引
1.2 表格相关元素
① table 元素
rows 得到表格中所有行的集合
cells 得到表格中所有单元格的集合(th和td)
insertRow() 在表格中插入一行,返回新插入的tr元素,参数为新行的位置,不指定则在最后添加
deleteRow() 删除表格中的一行,参数指定行的索引
② tableRow 元素(tr元素)
rowIndex 获取本行的索引
cells 获取本行内所有单元格的集合
insertCell() 在本行中插入一个单元格,方法返回新插入的td元素,参数是新单元格的位置,不指定则在最后添加
deleteCell() 删除本行中的一个单元格,参数指定单元格在本行的索引
③ tableCell 元素(th或td)
cellIndex 获取本单元格在行内的索引
1.3 快速创建元素
// 通用方法创建 option 元素
var option1 = document.createElement('option');
option1.innerHTML = '小乐';
option1.value = 'xiaole';
// 使用快捷方法创建 option 元素
var option2 = new Option('小乐','xiaole')
// 通用方法 创建 img 元素
var img1 = document.createElement('img');
img1.src = '100.jpg';
// 快捷方法创建 img 元素
var img2 = new Image();
img2.src = '100.jpg';
2 事件
2.1 事件监听
① 给元素监听事件的三种方式
-
把事件作为HTML标签的属性
<button onclick="code..."></button>
注:
- 这种方式没有使用到回调函数,函数在onclick中直接调用;
- 由于HTML标签的属性特点,如果行内用多个
onclick
属性设置事件,则只生效第一个,后面的事件均无效。
-
把事件作为元素对象的方法
元素对象.on事件名 = 回调函数function(){ code ...; }
注:由于程序顺序执行,如果给同一元素的同一事件设置多个回调函数,则后面的会覆盖前面的。
-
把事件作为addEventListener方法的参数(适用于IE9+)
元素对象.addEventListener('事件名', 回调函数function(){ code ...; })
注:
addEventListener
方法可给同一元素的同一事件绑定多个回调函数,触发事件时多个回调函数按监听顺序执行。该方法的第三个参数可设置事件在捕获阶段或是冒泡阶段触发。
-
兼容性方案:IE8及以下适用于:
attachEvent('on事件名', 回调函数);//添加监听 detachEvent('事件名', 回调函数);//解除监听
② 解除事件的监听
-
第一种方式和第二种方式监听的事件:
元素对象.on事件名 = null;
-
第三种方式监听的事件:
元素对象.removeEventListener('事件名', 函数名);
2.2 事件流
一个完整的事件触发流程会经历三个阶段:
捕获阶段: window -> document -> html -> body ->... -> 目标元素。(目标元素: 具体的发生了事件动作且不可再分的元素)
目标阶段: 找到了目标与元素,标记着捕获阶段的结束,冒泡阶段的开始。
冒泡阶段: 目标元素 -> ... -> body -> html -> document -> window
事件的回调函数在哪个阶段被执行?
事件的回调函数在冒泡阶段被执行,即事件默认在冒泡阶段被触发。
如何设置事件在哪个阶段触发?
如果是第三种方式监听的事件,addEventListener
第三个参数设置为 true
表示事件在捕获阶段触发,false
表示在冒泡阶段触发,默认值为 false
。
如果是第一种和第二种方式监听的事件,则在冒泡阶段触发且无法修改。
2.3 事件回调函数种 this 的指向
使用第二种、第三种监听事件,事件回调函数中
this
的值是触发事件的元素。-
使用第一种方式监听事件,属性值里面可以直接使用
this
,值是该元素<button onclick="console.log(this)"> <!--此处的this即为button元素-->
2.4 常用事件
① 鼠标事件
click 单击
dblclick 双击
contextmenu 右键单击
mouseover 鼠标悬停在元素上,建议用 mouseenter 代替
mouseout 鼠标离开元素,建议用 mouseleave 代替
mouseenter 鼠标悬停在元素上
mouseleave 鼠标离开元素
mousedown 鼠标按键按下
mouseup 鼠标按键抬起
mousemove 鼠标移动
mouseenter、mouseleave 与 mouseover、mouseout 的区别:
- mouseenter 和 mouseleave 事件,后代元素不会冒泡,符合实际场景
- mouseover 和 mouseout 事件,后代元素会冒泡,不符合实际场景,鼠标移入移出后代元素时也会触发设置在元素上的事件。
② 键盘事件
键盘事件一般监听给document
或文本框、文本域
keydown 键盘按键按下
keyup 键盘按键抬起
keypress 键盘按键按下(可输入字符才能触发,控制按键如:上下左右、shift、alt、ctrl等不能触发)
③ 文档事件
当获取元素的事件过早,元素还未加载出来时是获取不到的(如:把JS代码写到HTML代码前面),可以用这两个事件。
load 文档加载完毕,监听到window或者body元素
DOMContentLoaded 文档加载完毕
load 事件和 DOMContentLoaded 事件的区别:
- load 事件需等到页面中所有的一切(包括外部文件)加载完毕才能触发; DOMContentLoaded 事件只要页面中的元素加载完毕(不包括外部文件)就可以触发。
- DOMContentLoaded 只能使用 addEventListener 方法监听。
⑤ 表单事件
submit 表单提交的时候触发,只能监听给form元素
reset 表单重置的时候触发,只能监听给form元素
blur 失去焦点时触发,监听给表单控件元素(input、textarea 等)
focus 获取焦点时触发,监听给表单控件元素(input、textarea 等)
select 输入框中文字被选中时触发事件,监听给输入类表单控件
change 监听到输入框的触发条件:①输入内容改变 ②失去焦点;监听到下拉框select上的触发条件:下拉选项内容改变
⑥ 图片事件
load 图片文件加载完毕时触发
error 图片文件加载失败时触发
abort 图片加载中断时触发
注:图片加载失败后,如果给图片换一个正确的src,加载成功后也会触发一次load事件。
⑦ 其他事件
scroll 内容滚动时触发,监听给window(整个页面滚动)或者内容能够滚动的元素(内容溢出且overflow不为visible)
resize 视口大小发生变化时触发,只能监听给window
⑧ 动画和过渡事件
animationstart 动画开始时触发
animationiteration 动画每执行一次就触发一次
animationend 动画结束时触发
transitionstart 过渡开始,过渡开始时触发(在过渡延迟之后触发)
transitionrun 过渡运行,过渡开始运行时触发(在过渡延迟之前就触发)
transitionend 过渡结束时触发(过渡时间)
3 Event 对象
在触发DOM上某个事件时,会产生一个事件对象event,当中包含着所有与事件有关的信息,包括:导致事件的元素、事件的类型、其他与特定事件相关的信息。比如:鼠标事件的对象中有鼠标的位置信息,键盘事件的对象中有按下的键的信息。
3.1 Event对象的获取
-
使用第一种方式监听的事件:用关键字
event
。(event
其实是window
的属性,window.event
,.window
可省略,该属性指向当前触发的对象)<button onclick = "console.log(event)"></button> //或 <button onclick = "fn()"></button> function fn(){ console.log(event); }
-
使用第二、三种方式监听事件,回调函数自动接收参数,写一个形参即可(不一定叫
event
,叫什么都可以)。btn.onclick = function(event){//如果不写此处的event,也会输出event对象,因为event是window的属性,本作用域中没有event则去上层查找直至window一定可以找到 console.log(event); } btn.addEventListener("click",function(event){ console.log(event); })
3.2 鼠标事件对象 MouseEvent 的属性和方法
offsetX / offsetY 获取鼠标在 目标元素 上的位置(注:不一定是监听事件的元素)
pageX / pageY 获取鼠标在 页面 上的位置
clientX / clientY 获取鼠标在 视口 上的位置
screenX / screenY 获取鼠标在 屏幕 上的位置
button 鼠标按键的值: 0表示左键、1表示滚轮键、2表示右键
3.3 键盘事件对象 KeyboardEvent 的属性和方法
keyCode 获取键盘按键对应的ASCII值
which 同上
key 获取键盘按键对应的值(字符串)
3.4 所有类型的事件对象都有的属性和方法
type 返回事件名
timestamp 获取时间戳(触发事件时距离打开页面时的毫秒数)
target 获取目标元素
stopPropagation() 阻止冒泡
preventDefault() 阻止浏览器默认行为
3.5 阻止冒泡事件
防止该元素的祖先元素被冒泡
event.stopPrapagation();
3.6 阻止浏览器默认行为
浏览器的默认行为:
1. 单击了超链接元素,跳转
2. 表单的提交按钮和重置按键
3. 右键菜单
....
阻止浏览器默认行为:
//适用于第二、三种事件监听方式
event.preventDefault();
//适用于第二种事件监听方式(在回调函数中return false)
return false;
4 事件委托
原理: 把事件监听到祖先元素上,在事件回调函数中判断目标元素是否是要触发事件的元素。
事件委托的优势: ① 让新增的元素也具有事件。 ② 如果需要给大量的元素监听相同的事件,事件委托更节省资源。
5 DOM 对象深入分析
不同的元素、事件具有相同的属性,是因为它们有相同的原型,如:鼠标事件和键盘事件都有Event.prototype。
5.1 元素对象的原型链关系
以div为例:
div元素 -> HTMLDivElement.prototype -> HTMLElement.prototype -> Element.prototype -> EventTarget.prototype -> Object.prototype
5.2 事件对象的原型链关系
以鼠标事件为例:
鼠标事件对象 -> MouseEvent.prototype -> UIEvent.protptype -> Event.prototype -> Object.prototype
5.3 HTMLCollection 和 NodeList 的区别
① HTMLCollection对象
1. 获取HTMLCollection类型的集合的方式:getElementsByTagName()、getElementsByClassName()、元素.children、document.all
2. HTMLCollection中成员必须都是元素
3. HTMLCollection是动态的集合,在获取集合后,如果DOM结构中新增满足条件的元素,会自动更新到集合中。
4. HTMLCollection没有forEach方法。
② Nodelist对象
1. 获取Nodelist类型的集合的方式:getElementsByName()、querySelector()、元素.ChildNodes
2. Nodelist中成员可以是任意类型的节点
3. Nodelist是静态的集合,获取时有哪些节点就永远有哪些节点
4. Nodelist有forEach方法。