文章目录
EVENT
什么是事件
-
一个事件由什么东西组成
- 谁来触发事件:事件源
- 触发什么事件:事件类型
- 触发以后做什么:事件处理函数
var oDiv = document.querySelector('div') oDiv.onclick = function () {} // 谁来触发事件 => oDiv => 这个事件的事件源就是 oDiv // 触发什么事件 => onclick => 这个事件类型就是 click // 触发之后做什么 => function () {} => 这个事件的处理函数
- 我们想要在点击 div 以后做什么事情,就把我们要做的事情写在事件处理函数里面
var oDiv = document.querySelector('div') oDiv.onclick = function () { console.log('你点击了 div') }
- 当我们点击
div
的时候,就会执行事件处理函数内部的代码 - 每点击一次,就会执行一次事件处理函数
事件的绑定方式
事件的绑定方式有两种:
1、事件的监听语法
标签对象.addEventListener('事件类型', 回调函数, 冒泡还是捕获)
同一个标签对象、相同的事件类型,用这种方法可以同时绑定多个事件程序
但这种方法需要考虑兼容问题,详见下面事件监听。
2、on语法形式
标签对象.on事件类型 = 回调函数
同一个标签对象、相同的事件类型,只能绑定一个事件程序
一旦写了第二个事件,那么第一个就被覆盖了。
var oDiv = document.querySelector('div');
// on语法 同一个标签对象、相同的事件类型,只能绑定一个事件程序
oDiv.onclick = function(){ console.log(111) };
oDiv.onclick = function(){ console.log(222) };
oDiv.onclick = function(){ console.log(333) };
oDiv.onclick = function(){ console.log(444) };
//=> 点击一次div只会输出一次 444
// 事件监听语法 同一个标签对象、相同的事件类型,可以同时绑定多个事件程序
oDiv.addEventListener( 'click' , function(){ console.log(111) });
oDiv.addEventListener( 'click' , function(){ console.log(222) });
oDiv.addEventListener( 'click' , function(){ console.log(333) });
oDiv.addEventListener( 'click' , function(){ console.log(444) });
//=> 点击一次div会输出一次 111 222 333 444
事件监听
1、addEventListener
不是IE 7 8 的浏览器都可使用
语法: 元素.addEventListener('事件类型', 事件处理函数, 冒泡还是捕获)
false:默认,冒泡
true:捕获
oDiv.addEventListener('click', function () {
console.log('我是第一个事件')
}, false)
oDiv.addEventListener('click', function () {
console.log('我是第二个事件')
}, false)
- 当你点击 div 的时候,两个函数都会执行,并且会按照你注册的顺序执行
- 先打印
我是第一个事件
再打印我是第二个事件
- 注意: 事件类型的时候不要写 on,点击事件就是 click,不是 onclick
2、attachEvent
:IE 7 8 下使用,别的浏览器用会报错
语法: 元素.attachEvent('事件类型', 事件处理函数)
oDiv.attachEvent('onclick', function () {
console.log('我是第一个事件')
})
oDiv.attachEvent('onclick', function () {
console.log('我是第二个事件')
})
- 当你点击 div 的时候,两个函数都会执行,并且会按照你注册的顺序倒叙执行
- 先打印
我是第二个事件
再打印我是第一个事件
- 注意: 事件类型的时候要写 on,点击事件是 onclick
3、兼容函数
/*
参数1 要绑定事件的标签对象
参数2 事件类型
参数3 回调函数
*/
function myAddEvent( ele , type , fun){
// 判断 addEventListener这个方法是否存在
if(ele.addEventListener){
// 普通浏览器
ele.addEventListener(type , fun);
}else{
// 低版本IE浏览器
ele.attachEvent('on'+type , fun);
}
}
事件删除
1、on语法
给事件类型赋值绑定 空函数 或者 null空值
2、事件监听语法
`标签对象.removeEventListener( '事件类型' , 回调函数 )`
要删除 回调函数 必须是 绑定的 函数名称语法形式
如果 回调函数 是 匿名函数 语法形式 不能删除
<div>我是div</div>
<button>删除</button>
<script>
// 获取标签对象
var oDiv = document.querySelector('div');
var oBtn = document.querySelector('button');
// 给 div 绑定 点击事件
// oDiv.onclick = function(){ console.log(111) };
// 事件监听语法 绑定的匿名函数
oDiv.addEventListener( 'click' , function(){console.log(111)} );
oDiv.addEventListener( 'click' , fun1 );
oDiv.addEventListener( 'click' , fun2 );
oDiv.addEventListener( 'click' , fun3 );
function fun1(){console.log(2222)};
function fun2(){console.log(3333)};
function fun3(){console.log(4444)};
// 给 button 绑定 点击事件
// 点击时 删除div标签绑定的事件
oBtn.addEventListener('click' , function(){
// on语法绑定 只要 赋值 空函数 / null
// oDiv.onclick = function(){} ;
// oDiv.onclick = null ;
// 事件监听语法 删除 事件
// 匿名函数的语法形式 不能删除
oDiv.removeEventListener( 'click' , function(){ console.log(111) });
// 只能删除 函数名称语法形式
oDiv.removeEventListener( 'click' , fun1);
oDiv.removeEventListener( 'click' , fun3);
})
</script>
默认行为
-
比如我们在网页上点击鼠标右键的时候,会自动弹出一个菜单
-
比我们点击 a 标签的时候,我们不需要注册点击事件,他自己就会跳转页面
-
这些不需要我们注册就能实现的事情,我们叫做 默认事件
阻止默认行为
-
有的时候,默认事件有可能会和 JavaScript程序冲突,我们不希望浏览器执行默认事件,就需要阻止默认事件的发生。
- 比如我给 a 标签绑定了一个点击事件,点击的时候希望控制台输出地址是什么,而不是直接跳转链接
- 那么我们就要把 a 标签原先的默认跳转事件阻止,不让他执行默认事件
-
我们有两个方法来阻止默认事件
e.preventDefault()
非 IE 使用e.returnValue = false
IE 使用
-
我们阻止默认事件的时候也要写一个兼容的写法
<a href="https://www.baidu.com">点击我试试</a> <script> var oA = document.querySelector('a') oA.addEventListener('click', function (e) { e = e || window.event console.log(this.href) e.preventDefault ? e.preventDefault() : e.returnValue = false }) </script>
- 这样写完以后,你点击 a 标签的时候,就不会跳转链接了
- 而是会在控制台打印出 a 标签的 href 属性的值
<a href="https://www.baidu.com">百度</a>
<form action="./01_复习.html">
账号 <input type="text"><br>
密码 <input type="text"><br>
<button>跳转</button>
</form>
<script>
// 获取超链接标签对象
var oA = document.querySelector('a');
// 在回调函数中添加参数,参数名称任意定义,一般是event或者e
oA.addEventListener('click' , function(e){
console.log(111);
// 阻止默认事件的执行 写在任意位置都行
e.preventDefault() ;
})
// 阻止form标签的跳转效果
var oForm = document.querySelector('form');
// 表单标签 提交事件 是 submit
oForm.addEventListener( 'submit' , function(e){
// 阻止默认事件的执行 写在任意位置都行
e.preventDefault() ;
})
// 阻止鼠标右键弹出菜单栏
// 给整个html文档添加:contextmenu右键单击事件
document.addEventListener( 'contextmenu' , function(e){
// 阻止默认事件的执行 写在任意位置都行
e.preventDefault() ;
})
</script>
事件对象
-
什么是事件对象?
-
就是当你触发了一个事件以后,对该事件的一些描述信息
-
例如:
- 你触发一个点击事件的时候,你点在哪个位置了,坐标是多少
- 你触发一个键盘事件的时候,你按的是哪个按钮
-
每一个事件都会有一个对应的对象来描述这些信息,我们就把这个对象叫做 事件对象
-
浏览器给了我们一个 黑盒子,叫做
window.event
,就是对事件信息的所有描述- 比如点击事件
- 你点在了
0,0
位置,那么你得到的这个事件对象里面对应的就会有这个点位的属性 - 你点在了
10, 10
位置,那么你得到的这个事件对象里面对应的就会有这个点位的属性
oDiv.onclick = function () { console.log(window.event.X轴坐标点信息) console.log(window.event.Y轴坐标点信息) }
-
事件对象兼容性问题
在 IE低版本
里面用 window.event
,
在 高版本IE
和 Chrome
里面:直接在事件处理函数中定义形参
-
在每一个事件处理函数的行参位置,默认第一个就是 事件对象
oDiv.onclick = function (e) { // e 就是和 IE 的 window.event 一样的东西 console.log(e.X轴坐标点信息) console.log(e.Y轴坐标点信息) }
-
综上所述,我们以后在每一个事件里面,想获取事件对象的时候,都用兼容写法
oDiv.onclick = function (e) { e = e || window.event console.log(e.X轴坐标点信息) console.log(e.Y轴坐标点信息) }
-
事件对象指的是触发事件的标签对象,不一定是事件源
-
事件源是绑定事件的标签, 不一定就是触发事件的标签
点击事件的光标坐标点获取
-
事件对象.offsetX
和事件对象.offsetY
鼠标位置 距离 事件对象 左上角的 坐标位置
-
事件对象.clientX
和事件对象.clientY
是相对于浏览器窗口来计算的,不管你页面滚动到什么情况,都是根据窗口来计算坐标
鼠标位置 距离 视窗窗口 左上角的 坐标位置
-
事件对象.pageX
和事件对象.pageY
是相对于整个页面的坐标点,不管有没有滚动,都是相对于页面拿到的坐标点
鼠标位置 距离 html文档 左上角的 坐标位置
<style> *{ margin: 0; padding: 0; } body{ height: 5000px; } div{ width: 800px; height: 800px; background: pink; margin: 100px auto; display: flex; justify-content: center; align-items: center; } h1{ width: 600px; height: 600px; background: orange; display: flex; justify-content: center; align-items: center; } p{ width: 400px; height: 400px; background: steelblue; display: flex; justify-content: center; align-items: center; } </style> <body> <div> <h1> <p></p> </h1> </div> <script> var oDiv = document.querySelector('div'); oDiv.addEventListener('click' , function(e){ // e.target 是 触发事件的标签对象 console.log( e.target ); // e.offsetX e.offsetY // 鼠标位置距离 事件对象 左上角 的距离 console.log( e.offsetX , e.offsetY ); // e.clientX e.clientY // 不管谁是 事件对象 都是 距离 视窗窗口 左上角的距离 console.log( e.clientX , e.clientY ); // e.pageX e.pageY // 不管谁是 事件对象 都是 距离 html文档 左上角的距离 console.log( e.pageX , e.pageY ); // 如果页面没有滚动,那么最后两个数值是相同的 }) </script> </body>
点击按键信息(了解)
- 我们的鼠标一般都有两个按键,一个左键一个右键
- 我们的事件对象里面也有这个信息,确定你点击的是左键还是右键
- 我们使用
事件对象.button
来获取信息 0
为鼠标左键,2
为鼠标右键
常见的事件
- 我们在写页面的时候经常用到的一些事件
- 大致分为几类,浏览器事件 / 鼠标事件 / 键盘事件 / 表单事件 / 触摸事件
- 不需要都记住,但是大概要知道
浏览器事件
load
: 页面全部资源加载完毕scroll
: 浏览器滚动的时候触发
鼠标事件
click
:点击事件dblclick
:双击事件contextmenu
: 右键单击事件mousedown
:鼠标左键按下事件mouseup
:鼠标左键抬起事件mousemove
:鼠标移动mouseover
:鼠标移入事件,后代也可触发mouseout
:鼠标移出事件,后代也可触发mouseenter
:鼠标移入事件,后代不可触发mouseleave
:鼠标移出事件,后代不可触发
<style>
div{
width: 400px;
height: 400px;
background: pink;
}
p{
width: 200px;
height: 200px;
background: orange;
}
</style>
</head>
<body>
<div>
<p></p>
</div>
<script>
// 获取标签对象
var oDiv = document.querySelector('div');
// 单击事件
oDiv.addEventListener( 'click' , function(){
console.log( '鼠标单击事件' );
})
// 双击事件
oDiv.addEventListener( 'dblclick' , function(){
console.log( '鼠标双击事件' );
})
// 右键单击事件
oDiv.addEventListener( 'contextmenu' , function(e){
console.log( '鼠标右键单击事件' );
})
// 鼠标按下
oDiv.addEventListener( 'mousedown' , function(){
console.log( '鼠标按下事件' );
})
// 鼠标抬起
oDiv.addEventListener( 'mouseup' , function(){
console.log( '鼠标抬起事件' );
})
// 鼠标移动
// 给div标签绑定事件,只有在div标签中移动鼠标,才会触发事件
oDiv.addEventListener( 'mousemove' , function(){
console.log( '鼠标移动事件' );
})
// 鼠标的移入事件
// 鼠标经过div的边界线时 触发事件
// div可以触发,div的后代标签也可以触发
oDiv.addEventListener( 'mouseover' , function(){
console.log('鼠标移入了111');
})
// div可以触发,div的后代标签不能触发
/oDiv.addEventListener( 'mouseenter' , function(){
console.log('鼠标移入了222');
})
// 鼠标的移出事件
// div可以触发,div的后代标签也可以触发
oDiv.addEventListener( 'mouseout' , function(){
console.log('鼠标移出了333');
})
// div可以触发,div的后代标签不能触发
oDiv.addEventListener( 'mouseleave' , function(){
console.log('鼠标移出了444');
})
</script>
键盘事件
keyup
: 键盘抬起事件keydown
: 键盘按下事件keypress
: 键盘按下再抬起事件,有些按键不会触发 keypress,实际项目中一般不用
1、键盘事件不能直接添加给所有的标签对象
例如给div标签直接添加键盘事件,就不支持
2、可以获取鼠标焦点的标签,可以直接支持键盘事件
input textarea select button a
3、可以给特殊标签添加键盘事件
document
document.documentElement
document.body
这些也可以触发键盘事件
-
在键盘事件里面最主要的就是要做两个事情
- 判断点击的是哪个按键
- 有没有组合按键,shift + a / ctrl + b / …
-
首先要明确一个问题,就是是不是所有元素都可以绑定键盘事件
- 我们说事件有一个关键的东西是,该事件是由谁来触发的
- 一个 div 元素在页面上,我怎么能让一个键盘事件触发在 div 上
- 所以说,我们一般只给能在页面上选中的元素(表单元素) 和
document
来绑定键盘事件
document.onkeyup = function () { // code.. } oInput.onkeyup = function () { // code.. }
确定按键
-
我们的键盘上每一个按键都有一个自己独立的编码
-
我们就是靠这个编码来确定我们按下的是哪个按键的
-
我们通过
事件对象.keyCode
或者事件对象.which
来获取 -
为什么要有两个呢,是因为 FireFox2.0 (低版本火狐)不支持
keycode
所以要用which
document.keyup = function (e) { // 事件对象的兼容写法 e = 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,否则得到 falseshiftKey
:shift 键按下得到 true,否则得到 falsectrlKey
:ctrl 键按下得到 true,否则得到 false
-
我们就可以通过这三个属性来判断是否按下了
document.onkeyup = function (e) { e = e || window.event keyCode = e.keyCode || e.which if (e.altKey && keyCode === 65) { console.log('你同时按下了 alt 和 a') } }
表单事件
-
change
: 失去焦点,并且表单内容改变触发的事件 -
input
: 输入表单内容时触发的事件 -
submit
: 提交表单时触发的事件,添加给form标签 -
focus
: 获取焦点时触发的事件,必须是可以获取焦点的标签
input
、select
、textarea
、button
、a
… -
blur
: 失去焦点时触发的事件
触摸事件
只有 移动端 设备支持的事件
touchstart
: 触摸开始事件touchend
: 触摸结束事件touchmove
: 触摸移动事件
特殊事件
-
过渡
transitionstart
: 过渡开始transitionend
: 过渡结束
-
动画
animationstart
: 动画开始animationend
: 动画结束
<style>
div{
width: 100px;
height: 100px;
background: pink;
transition: all 2s;
}
div:hover{
width: 300px;
height: 300px;
background: blue;
}
</style>
<body>
<div></div>
<script>
var oDiv = document.querySelector('div');
oDiv.addEventListener( 'transitionstart' , function(){
console.log('过渡开始了');
})
</script>
</body>
事件委托
- 就是把我要做的事情委托给别人来做
- 因为我们的冒泡机制,点击子元素的时候,不管子元素有没有点击事件,只要父元素有点击事件,那么就可以触发父元素的点击事件
- 所以我们就可以把子元素的事件委托给父元素来做
1、为什么要用事件委托?
如果页面上本身没有<li>,但是我通过代码添加了一些<li>,添加进来的<li>是没有点击事件的,每次动态的操作完<li>以后都要重新给<li>绑定一次点击事件,比较麻烦。
这个时候只要委托给<ul>就可以了,因为新加进来的<li>也是<ul>的子元素,点击的时候也可以触发<ul>的点击事件。
2、事件委托是一种给标签添加事件效果的方式方法,一般用于给动态生成的标签添加事件。
3*、是给一直存在的、不是动态生成的父级标签添加事件,通过事件对象判断触发事件的标签,执行不同的程序代码。并不是直接给动态生成的标签添加事件。
4、如果一个父级标签里面有多个子级标签,那么就需要通过判断来确定是哪个标签触发了事件。
5、如果有多个父级标签,只要不引起判断(用e.target)的冲突,给谁加都行。
6、<li>的点击事件,不能委托给<ul>的鼠标移入事件。
7、事件委托优缺点:
优点:
1)不用循环遍历给每一个标签添加事件,程序的执行效率就会提高。
2)如果是动态生成的标签,不用再次绑定事件。
缺点:
需要给标签中添加一些程序执行时需要的数据数值
target
-
target 这个属性是事件对象里面的属性,表示你点击的目标
-
当你触发点击事件的时候,你点击在哪个元素上,target 就是哪个元素
-
这个 target 也不兼容,在 IE 下要使用 srcElement
-
e.target.tagName
这个属性的属性值是大写英文的标签名称
,可以用来区分不同的标签 -
相同标签,可以通过设定id属性、class属性、name属性等进行区分。
e.target 触发事件的标签对象 数据结构就是一个标准的、DOM操作获取的、独立的标签对象 支持所有的 DOM 操作
<body> <ul> <li>1</li> <li>2</li> <li>3</li> </ul> <script> var oUl = document.querySelector('ul'); oUl.addEventListener('click', function (e) { e = e || window.event; var target = e.target || e.srcElement; console.log(target); }) </script> </body>
- 上面的代码,当你点击 ul 的时候,target 就是 ul
- 当你点击在 li 上面的时候,target 就是 li
委托
-
这个时候,当我们点击 li 的时候,也可以触发 ul 的点事件
-
并且在事件内不,我们也可以拿到你点击的到底是 ul 还是 li
-
这个时候,我们就可以把 li 的事件委托给 ul 来做
<body> <div> <a href="JavaScript:;">我是超链接标签</a> <p>我是p标签</p> <span>我是span标签</span> <h1 class="h1">我是h1标签1</h1> <h1 id="h1">我是h1标签2</h1> <h1 name="h1">我是h1标签3</h1> <a href="JavaScript:;">我是超链接标签</a> </div> <script> // 用事件委托语法形式,给标签添加事件效果 // 获取 父级标签对象 var oDiv = document.querySelector('div'); // 直接给父级标签,添加点击事件 oDiv.addEventListener('click' , function(e){ // e.target 是 触发事件的标签对象 // console.dir( e.target ); // 根据不同的条件,只要可以区分不同的标签就可以 if( e.target.tagName === 'A' ){ // 如果标签名称是 A ,也就是超链接标签 console.log( '您点击的是a标签' ); }else if( e.target.className === 'h1' ){ // 如果 标签 class属性值 是 h1 console.log( '您点击的是第一个h1标签' ); }else if( e.target.innerHTML === '我是h1标签3' ){ // 如果 标签 内容是 指定的内容 console.log( '您点击的是第三个h1标签' ); } }) </script> </body>