一、event事件
事件:是指用户在某事务上由于某种行为所执行的操作;(对页面元素的某种操作)
事件的组成:
触发谁的事件:事件源
触发什么事件:事件类型
触发以后做什么:事件处理函数
// 事件源.事件类型=事件处理函数
div1.onclick=function(){
当点击div1对象中任意位置上时,
执行事件处理函数中的代码
}
事件类型:
(1)常见事件之浏览器事件:
onload:当页面内容加载完毕时,触发(调用)
onresize:窗口大小发生变化时,触发
onscroll:滚动距离发生变化时,触发
注意:该事件一般是绑定在window对象或者是document对象上
(2)常见事件之鼠标事件:
onclick:鼠标单击时,触发
ondblclick:鼠标双击事件
onmouseover:鼠标移入事件
onmouseout:鼠标移出事件
onmouseenter:鼠标移入事件(不冒泡)
onmouseleave:鼠标移出事件(不冒泡)
onmousedown:鼠标左键按下事件
onmouseup:鼠标左键抬起事件
oncontextmenu:鼠标右键单击事件
onselecstart:选中事件(不被input和textarea标签支持)
onselect:选中事件(支持input和textarea标签)
(3)常见事件之键盘事件:
onkeydown : 键盘按下事件
onkeyup : 键盘释放事件
onkeypress : 产生可打印字符事件
注意:键盘事件绑定的位置,要么是document,要么是input输入框
(4)表单事件:
onchange : 表单改变事件(失去焦点时触发)
oninput :表单输入事件(输入时触发)
onsubmit :表单提交事件(点击submit时触发)
onfocus :获得焦点事件
onblur :失去焦点事件
(5)触摸事件(移动端):
ontouchstart :触摸开始
ontouchmove :触摸移动
ontouchend : 触摸结束
(6)加载事件:onload
(7)其他事件:
ontransitionend :过渡结束的时候触发
onanimationend :动画结束的时候触发
事件对象:
当触发事件时,对该事件的一些描述信息所组成的对象。事件对象是由系统给的,不是我们自己创建的
怎么样获取事件对象?
1)一般情况下, 在事件绑定中的函数里, 可以通过window. event来获取事件对象
2)在事件处理函数中的第一个参数就是系统自动生成的事件对象
二、事件流
事件的传播:
事件从开始触发到执行结束的整个过程,也就是事件的传播过程,我们称之为事件流。
注意:
1)只会传播同类事件
2.)只会从点击元素开始按照 html 的结构逐层向上元素的事件会被触发
3.)内部元素不管有没有该事件,只要上层元素有该事件,那么上层元素的事件就会被触发
事件的执行机制:
当元素触发一个事件时,其父元素也会触发相同类型的事件,父元素的父元素也会触发相同类型的事件;执行顺序由里到外;
事件传播的方式:冒泡false、捕获true
捕获阶段:由外到里,或者说是由大到小,先执行window对象中相同类型的事件,然后再向里执行,直到当前所触发的目标对象结束
目标阶段:当前所触发事件的对象
冒泡阶段:由里到外,或者说是由小到大,先执行当前目标对象中的事件,然后在执行结构父级中相同类型的事件,逐层向上级执行相同类型的事件,直到最顶层的window对象
注意:
捕获的执行顺序优先于冒泡的执行顺序;
事件执行的流程是先捕获阶段=>再目标元素阶段=>最后冒泡阶段。
目标元素的事件是在目标阶段执行,其他事件会在冒泡阶段执行。每个事件只会执行一次,也就是说如果在冒泡阶段执行了事件,就不会在捕获阶段执行。
三、事件监听器
事件的绑定方式:
//事件绑定在行内
<button onclick="alert(123)">按钮1</button>
<button onclick="fn()">按钮2</button>
//使用on加事件类型绑定事件
//现在给一个注册事件都是使用 onxxx的方式,但是只能给一个元素注册一个相同类型的事件
oDiv.onclick = function () {
console.log('我是第一个事件')
}
oDiv.onclick = function () {
console.log('我是第二个事件')
}
//当你点击的时候,只会执行第二个,第一个就没有了
//所以可以用事件监听的方式去给元素绑定事件 addEventListener()
事件监听:
事件源.addEventListener("事件类型",事件处理函数,冒泡还是捕获):非IE低版本浏览器使用
事件源.attachEvent("事件类型",事件处理函数,冒泡还是捕获):IE低版本浏览器使用
//addEventListener : 不用写 on
//addEventListener : 一般是三个常用参数
//addEventListener : 顺序注册,顺序执行;
//第三个参数:是否在捕获阶段执行,true在捕获阶段执行,false在冒泡阶段执行
oDiv.addEventListener('click', function () {
console.log('我是第一个事件')
}, false)
oDiv.addEventListener('click', function () {
console.log('我是第二个事件')
}, false)
//attachEvent : 两个参数
//attachEvent : 顺序注册,倒叙执行
oDiv.attachEvent('onclick', function () {
console.log('我是第一个事件')
})
oDiv.attachEvent('onclick', function () {
console.log('我是第二个事件')
})
事件监听的兼容写法:
if(div1.attachEvent){
div1.attachEvent("click",fn1)
}else{
div1.addEventListener("click",fn1)
}
移除事件监听(事件解绑):
(1)标签.on类型=函数绑定的事件,是在给对象的on类型属性设置值为函数,未绑定前为null,所以这种绑定方式绑定的事件,可以将标签.on类型属性赋值为null即可解绑。
var btn = document.querySelector('button')
btn.onclick = function() {
console.log('这是按钮的单击事件')
// 将给btn绑定的事件解绑
btn.onclick = null
}
(2)非IE低版本浏览器:事件源.removEventListener(事件类型,事件处理函数)
IE低版本浏览器:事件源.detachEvent(事件类型,事件处理函数)
btn.addEventListener('click', fn)
function fn() {
console.log('这是btn的单击事件')
// 将给btn绑定的事件解绑
btn.removeEventListener('click', fn)
}
//事件侦听器绑定事件时使用的是匿名函数,那这个事件解绑不了了
移除事件监听的兼容写法:
btn.onclick=function(){
if(div1.removeEventListener){
div1.removeEventListener("click",fn1)
}else{
div1.detachEvent("click",fn1)
}
}
四、事件对象
事件对象
//兼容所有浏览器的写法:
btn.onclick = function(e){
var ev = e || window.event
console.log(ev);
}
获取事件类型
//e.type 事件的类型
btn.onclick=function(e){
var e = e || window.event;
console.log(e.type); // MouseClick
}
获取鼠标按键码
使用 事件对象.button 来获取信息 ,返回的是数字
0 为鼠标左键, 1表示鼠标滚轮,2 为鼠标右键
btn.onmousedown = function(e){
var ev = e || window.event;
var code = ev.button;
if(code == 0){
console.log("您点击的是左键");
}else if(code == 1){
console.log("您点击的滚轮");
}else if(code == 2){
console.log("您点击的是右键");
}else{
console.log("不知道你点击的是什么");
}
}
获取键盘按键码
我们一般只给能在页面上选中的元素(表单元素) 和 document 来绑定键盘事件
我们的键盘上每一个按键都有一个自己独立的编码
我们就是靠这个编码来确定我们按下的是哪个按键的
事件对象.keyCode 或者 事件对象.which 来获取
因为 FireFox2.0 不支持 keycode 所以要用 which
// e.keyCode || e.which
document.onkeypress=function(e){
//事件对象的兼容写法
var ev = e || window.event;
//键盘码的兼容写法
var keyCode = e.keyCode || e.which
console.log(keyCode);
}
常见的键盘码(了解)
8: 删除键(delete)
9: 制表符(tab)
13: 回车键(ebter)
16: 上档键(shift)
17: ctrl 键
18: alt 键
27: 取消键(esc)
32: 空格键(space)
组合按键:组合按键最主要的就是 alt / shift / ctrl 三个按键
在我点击某一个按键的时候判断一下这三个键有没有按下,有就是组合了,没有就是没有组合
事件对象里面也为我们提供了三个属性
altKey :alt 键按下得到 true,否则得到 false
shiftKey :shift 键按下得到 true,否则得到 false
ctrlKey :ctrl 键按下得到 true,否则得到 false
document.onkeyup = function (e) {
e = e || window.event
keyCode = e.keyCode || e.which
if (e.shiftKey && keyCode === 97) {
console.log('你同时按下了 shift 和 a')
}
}
阻止事件冒泡
// e.stopPropagation() || e.cancelBubble=true
//第一种
small.onclick=function(e){
var ev = e || window.event;
ev.stopPropagation();
console.log(this.innerText);
console.log("小盒子的内容完毕");
}
//第二种
small.onclick=function(e){
var ev = e || window.event;
ev.cancelBubble=true;
console.log(this.innerText);
console.log("小盒子的内容完毕");
}
//兼容写法:
small.onclick=function(e){
console.log(this.innerText);
console.log("小盒子的内容完毕");
var ev = e || window.event;
if(ev.stopPropagation){
ev.stopPropagation
}else{
ev.cancelBubble=true;
}
}
阻止默认行为
默认行为,就是不用我们注册,它自己就存在的事情
比如我们点击鼠标右键的时候,会自动弹出一个菜单
比如我们点击 a 标签的时候,我们不需要注册点击事件,他自己就会跳转页面 ...
这些不需要我们注册就能实现的事件,我们叫做 默认事件
具有默认行为的常见的两个标签:
//链接:往属性href指定的地址跳转
<a href="/index.php">点我</a>
//提交按钮:往form表单属性action指定的地址跳转
<input type=”submit”>
阻止默认行为(阻止默认事件):
给链接地址设置为javascript:;或 javascript:void(0)
e.preventDefault() : 非 IE 使用
e.returnValue = false :IE 使用
return false (只针对事件绑定)
我们阻止默认事件的时候也要写一个兼容的写法
function stopDefault(event) {
var e = event || window.event;
if (e.preventDefault){
e.preventDefault(); // w3c标准浏览器
}else{
e.returnValue = false; // IE浏览器
}
}
获取鼠标坐标点
(1)光标相对于当前元素的坐标点(是相对于你点击的元素的边框内侧开始计算 ):offsetX、offsetY
(2)光标相对于浏览器左上角的坐标点(是相对于浏览器窗口来计算的,不管你页面滚动到什么情况,都是根据窗口来计算坐标):clientX、clientY
(3)光标相对于页面上左上角的坐标点(是相对于整个页面的坐标点,不管有没有滚动,都是相对于页面拿到的坐标点):pageX、pageY
注意:
一般情况下,属性后面是以left、top、 width、height结尾的,都是针对元素的操作
如果属性后面是以x、y结尾,那么一般是针对坐标点的操作
事件委托
概念: 让父标签处理子标签的事件事件委托原理?
事件冒泡 - 点击子标签能触发父标签的事件
就是把原本需要绑定在子元素上的事件委托给它的父元素
因为我们的冒泡机制,点击子元素的时候,也会同步触发父元素的相同事件 ,所以我们就可以把子元素的事件委托给父元素中相同类型的事件
事件触发:一旦操作元素时,不管该元素有没有该事件类型,只要它父级元素中有该事件类型,就会触发结构父级中该事件类型
获取精准的目标元素
事件对象.target
获取标签名
标签.tagName
事件委托的优点:
(1)减少事件注册,节省了内存的占用
(2)提高性能和效率
(3)新增的DOM元素无需再次注册事件
(4)动态添加的标签也能有事件