DOM二级事件
1、什么是事件?
事件分为两部分:
1)行为本身
//1)行为本身:浏览器天生赋予其的行为:onclick、onmouseover(onmouserenter)、onmouseout(onmouseleave)、
// onmousemove、onmousedown、onmouseup、onmousewheel(鼠标滚轮滚动行为)、onscroll(滚动条滚动行为)、
// onresize(window.onresize浏览器窗口大小改变事件)、onload、onunload(浏览器关闭)
// onfocus(文本框获取焦点行为)、onblur(文本框失去焦点行为)、onketdown、onkeyup(键盘按下和抬起行为)...
// ->哪怕没有给上述的行为绑定方法,时间也是存在的,当我们点击这个盒子的时候,同样会触发它的onclick行为,只是
// 什么事情都没做而已
2)事件绑定
//2)事件绑定:给元素的某一个行为绑定方法
//DOM 0级事件绑定
//->把匿名函数定义的部分当做一个赋值给odiv的点击行为(函数表达式)
let odiv = document.getElementById('div1')
odiv.onclick = function(){
//->当触发odiv的click行为的时候,会把绑定的这个函数执行
}
//->onclick这个行为定义在当前元素的私有属性上
//DOM 2级事件绑定
odiv.addEventListener('click',function(){
alert(this)
},false)
//->addEventListener这个属性是定义在当前元素所属EventTarget这个类的原型上的
MouseEvent:鼠标事件对象
let odiv = document.getElementById('div1')
//->把匿名函数定义的部分当做一个赋值给odiv的点击行为(函数表达式)
//->当我们触发#div1的点击行为的时候,会执行对应绑定上的方法
//->重要:不仅仅把绑定的方法执行了,而且浏览器还默认的给这个方法传递了一个参数值
//->MouseEvent:鼠标事件对象
//1)它是一个对象数据类型值,里面包含了汗多的属性名和属性值,这些都是用来记录当前鼠标的相关信息的
//2)MouseEvent -->UIEvent -->Event -->Object //原型链
//3)MouseEvent记录的是页面中唯一一个鼠标每一次触发时候的相关信息,和到底是在哪个元素上触发的没有关系
关于事件对象MoiseEvent的兼容问题
//->1)事件对象本身的获取存在兼容问题:标准浏览器中是浏览器给方法传递的参数,我们只需要定义形参e就可以获取到;
//在IE6~8中浏览器不会给方法传递参数,我们如果需要的话,需要到window.event中获取查找
//-> e = e || window.event
odiv.onclick = function(e){
e = e || window.event
//->e.type:存储的是当前鼠标触发的行为类型:"click"
//-> e.clientX/e.clientY:当前鼠标触发点距离当前屏幕左上角的x/y轴的坐标值
//->e.target:事件源,当前鼠标触发的是哪个元素,那么它存储的就是哪个元素,但是在IE6~8中不存在这
//个属性(e.target的值是undefined),使用e.srcElement来获取事件源
e.target = e.target || e.srcElement
//->e.pageX/e.pageY:当前鼠标触发点距离body左上角(页面第一屏幕最左上端)的x/y轴的坐标,但是ie6~8中没有这个
//属性,我们通过使用clientY + 滚动卷去的高度来获取也可以
// e.pageX = e.pageX || (e.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft))
// e.pageY = e.pageY || (e.clientX + (document.documentElement.scrollTop || document.body.scrollTop))
//->e.preventDefault:阻止浏览器的默认行为,在ie6~8中没有这个方法,需要使用e.returnValue = false来代替
// e.preventDefault ? e.preventDefault() : e.returnValue = false;
//return false //和上述的代码一样的效果,都是在阻止默认的行为
//->e.stopPropagation:阻止事件的冒泡传播,在ie6~8中不兼容,使用e.cancelBubble = true来代替
// e.stopPropagation ? e.stopPropagation() : e.cancelBubble = true;
console.log(e)
}
document.body.onclick = function(e){
console.log(e.pageX)
console.log(e.clientX)
}
let input1 = document.getElementById('input1')
input1.onkeyup = function(e){
// -> KeyboardEvent
// -> e.keyCode:当前键盘上每一个键对应的值
}
事件的默认传播机制
● 捕获阶段:从外向内依次查找元素
● 目标阶段:当前事件源本身的操作
● 冒泡阶段:从内到外依次触发相关行为(最常用的就是冒泡阶段)
注意:使用DOM 0级事件绑定给元素的某一个行为绑定的方法,都是在行为触发后的冒泡阶段把方法执行的
addEventListener参数解释
//addEventListener->第一个参数是行为的类型 第二个参数是给当前的行为绑定的方法 第三个参数是控制在哪个阶段发生
//true:在捕获阶段发生 false 在冒泡阶段发生
document.body.addEventListener('click',function(){
console.log('body')
},true)
事件委托
● 利用事件的冒泡传播机制(触发当前元素的某个行为,它父级所有元素的相关行为都会被触发),如果一个容器中有很多元素都要绑定点击事件,我们没必要一个个的绑定,只需要给最外层容器绑定一个点击事件即可,在这个方法执行的时候,通过事件源的区分来进行不同的操作
委托函数封装
function binEvent(elem, type, selector, fn) {
if (fn == null) {
fn = selector
selector = null
}
elem.addEventListener(type, function (e) {
let target;
if (selector) {
//有代理代理
target = e.target
console.log(e)
if(target.matches(selector)){
fn.call(target,e)
}
} else {
//不是代理
fn(e)
}
})
}
DOM0级事件和二级事件的区别
//->使用DOM2级事件绑定,其实是让box通过原型链一直找到EventTarget这个内置类原型上的addEventListener方法实现
//->DOM0级事件绑定:只能给一个元素的某一个行为绑定一次方法,第二次绑定的会把前面的覆盖掉
let box = document.getElementById('div1')
// box.onclick = function(){
// console.log("1")
// }
// box.onclick = function(){
// console.log("2")
// }
//->DOM2:可以给某一个元素的同一个行为绑定多个不同的方法
box.addEventListener('click',function(e){
console.log('1')
},false)
box.addEventListener('click',function(e){
console.log('2')
},false)
//->DOM2:DOM0中的行为类型,DOM2一样可以绑定;而且DOM2中还提供了一些DOM0没有的行为类型->
//DOMContentLoaded:当页面中的DOM结构(HTML结构加载完成)触发的行为
document.addEventListener('DOMContentLoaded',function(e){
console.log('oj8k')
},false)
//2、window.onload = function(){} ->当页面中的所有资源都加载完成(图片、HTML结构、音视频...)才会执行后面的
//函数;并且在一个页面中只能用一次,后面再写会把前面的覆盖掉; ->因为它是采用DOM0事件绑定,所以只能绑定一次
//jQuery:$(document).ready(function(){}) -> $(function(){})
//只要当页面中的HTML结构加载完成就会执行对应的函数;并且在同一个页面中可以出现多次
//->DOM2事件绑定
//->并且绑定的行为是DOM2中新增加的 DOMContentLoaded 事件
// window.addEventListener('load',function(){},false)
/*
//3、DOM2
function fn1(e){
console.log(this) //this -> box
}
box.addEventListener('click',fn1,false)
//->移除的时候需要保证三个参数:行为、方法、哪个阶段发生 一点都不能差 ->在使用DOM2绑定的时候,一般使用实名函数
box.removeEventListener('click',fn1,false)
*/
// 4、
//->只能给某个元素的同一个行为绑定多个"不同"的方法(如果方法相同了只能留一个)
//->当行为触发,会按照绑定的先后顺序依次把绑定的方法执行
//->执行的方法中的this是当前被绑定事件的元素本身
//->事件池:是用来存储当前元素行为绑定的方法的(浏览器自带的机制)
//->在IE6-8浏览器中,不支持addEventListener,如果想实现DOM2事件绑定只能用attachEvent/detachEvent
box.attachEvent('onclick',fn1)
//->它只有两个参数,不能像addEventListener那样控制在哪个阶段发生,默认只能在冒泡阶段发生
//->行为需要添加'on'(和DOM0特别类似)
//->可以绑定多个事件
function fn1(e){
console.log(this) //this -> box
}
BOM一些属性
// navigator.userAgent ->打印浏览器属性
// location
location.protocol //协议
location.host //域名
location.pathname //路径
location.search //问号后面的参数
location.hash //#后面的参数
location.href //整个url集合