一、定义
js与html之间的交互是通过事件实现的。
事件,就是文档或浏览器窗口中发生的一些特定的交互瞬间。
诸如 click、load 和 mouseover,都是事件的名字
二、事件处理程序
响应某个事件的函数就叫做事件处理程序(或事件侦听器)。
js
中事件分为三种:0级事件(事件绑定)、2级事件(事件监听)、3级事件
0级事件和2级事件用来和用户交互的,3级事件是当页面出现变动的时候使用
事件参数:在事件执行的时候,浏览器会给事件函数传递一个参数,是个对象–>事件对象[鼠标事件对象,键盘事件对象]
通过 JavaScript 指定事件处理程序的传统方式,就是将一个函数赋值给一个事件处理程序属性。每个元素(包括 window 和 document)都有自己的事件处理程序属性,这些属性通常全部小写,例如 onclick
。将这种属性的值设置为一个函数,就可以指定事件处理程序,如下所示:
var btn = document.getElementById('mybtn');
//使用普通函数:
btn.onclick = function(){
alert("我用来测验onclick事件");
}
//箭头函数版:
btn.onclick = e => {
console.log(e);
};
(1)默认事件
1> 浏览器默认事件行为
- 浏览器中点击右键弹出快捷菜单
- 点击超级链接跳转刷新页面
- 表单中点击提交按钮能够提交表单
2> 阻止默认事件:
语法:
①
event.preventDefault();
②在语句最后
return false;
示例:
<body> <form> <input type="submit" value="提交"> </form> </body> <script> const input = document.querySelector("input"); input.onclick = function(e){ e.preventDefault();//第一种写法(常用) return false;//第二种写法,写一个即可 //此时阻止了刷新页面这一默认事件 } </script>
(2)0级事件
0级事件以"on"开头,因此click 事件的事件处理程序就是 onclick
,load 事件的事件处理程序就是 onload
。
(3)事件冒泡
1> 事件冒泡行为:
(事件流的一种)当点击到页面中的某个元素的时候,点击事件会一层一层的向上传递(从自己到祖先)===>向上冒泡
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rJATEeNe-1664004913282)(%E4%BA%8B%E4%BB%B6%E5%86%92%E6%B3%A1.png)]
例如:
<style>
.big{
width: 200px;
height: 200px;
background-color: orange;
}
.middle{
width: 150px;
height: 150px;
background-color: purple;
}
.box{
width: 100px;
height: 100px;
background-color: #58a;
}
.little{
width: 50px;
height: 50px;
background-color: cyan;
}
</style>
<body>
<section class="big">
<section class="middle">
<section class="box">
<div class="little"></div>
</section>
</section>
</section>
</body>
<script>
const big = document.querySelector('.big'),
middle = document.querySelector('.middle'),
box = document.querySelector('.box'),
little = document.querySelector('.little');
big.onclick = function(e){
e.preventDefault();
console.log("我是大盒子");
}
middle.onclick = function(e){
e.preventDefault();
console.log("我是中等盒子");
}
box.onclick = function(e){
e.preventDefault();
console.log("我是box");
}
little.onclick = function(e){
e.preventDefault();
console.log("我是小盒子");
}
</script>
此时代码似乎是点击小盒子时,控制台就会打印出“我是小盒子”, 然而事实上,它会将他的所有父级的点击任务也完成,就是说,他会依此打印出(从自己到父级)
我是小盒子
我是box
我是中等盒子
我是大盒子
这种行为就叫做事件冒泡。
2> 阻止事件冒泡:
语法:event.stopPropagation();
运用:(只会阻止当前元素的冒泡,不会涉及子级)
big.onclick = function(e){
e.preventDefault();
e.stopPropagation();//只阻止big的冒泡
console.log("我是大盒子");
}
middle.onclick = function(e){
e.preventDefault();
e.stopPropagation();//只阻止middle的冒泡
console.log("我是中等盒子");
}
box.onclick = function(e){
e.preventDefault();
e.stopPropagation();//只阻止box的冒泡
console.log("我是box");
}
little.onclick = function(e){
e.preventDefault();
e.stopPropagation();//只阻止little的冒泡
console.log("我是小盒子");
}
(4)2级事件
语法:
元素.addEvenetListener('事件名称', callback, 是否捕获事件)
事件捕获:
(事件流的一种)2级事件也有冒泡,但比0级事件多了一项事件捕获阶段,如果想让一个事件的执行是从上到下(从父级到自己),可以开启捕获。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cbwjUALq-1664004913284)(%E4%BA%8B%E4%BB%B6%E6%8D%95%E8%8E%B7.png)]
示例:
big.addEventListener('click', function(e) {
console.log('橙色');
},true)
midlle.addEventListener('click', function(e) {
console.log('紫色');
},true)
box.addEventListener('click', function(e) {
console.log('蓝色');
},true)
little.addEventListener('click', function(e) {
console.log('靛青色');
},true)
/*
此时如果点击蓝色盒子,会这么打印:
橙色
紫色
蓝色
*/
七、鼠标事件:
1> 事件:
鼠标事件 | 何时触发 |
---|---|
click | 左单击 |
dblclick | 左双击 |
contextmenu | 右单击 |
mousedown | 按下任意鼠标按钮 |
mouseenter | 鼠标进入元素,不冒泡 |
mouseleave | 鼠标离开元素,不冒泡 |
mousemove | 鼠标在元素里移动 |
mouseout | 在鼠标指针位于一个元素上方,然后用户将其移入另一个元素时触发 |
mouseover | 在鼠标指针位于一个元素外部,然后用户将其首次移入另一个元素边界之内时触发 |
mouseup | 在用户释放鼠标按钮时触发 |
mousewheel | 鼠标的滚轮;wheelDelta > 0 向下滚动,wheelDelta < 0 向上滚动 |
focus | 得到焦点,常用于鼠标进入input框中,或者页面可视化区域 |
blur | 失去焦点,常用于鼠标进入input框中,或者页面可视化区域 |
change | select标签选择内容 |
selectedIndex | 哪一个option标签被选中(下标) |
slectOptions | 哪一个option标签被选中(元素本身) |
input | 当在标签里边输入内容的时候 |
click
左单击
//0级事件:
box.onclick = function (e) {//左击事件
console.log(e);//作为点击事件的参数,打印出所有点击事件属性
console.log( '我点击了:', e.target );
};
//2级事件:
box.addEventListener('click', function(e) {
console.log("点击了box");
})
dblclick
左双击(双击时,单击事件也会触发)
box.ondblclick = function () {
console.log( '双击了box' )
};
contextmenu
右单击
box.oncontextmenu = function () {
console.log( '右击了鼠标' );
};
mousewheel
鼠标滚轮
box.onmousewheel = e => {//wheel[滚动]
if( e.wheelDelta > 0 ){
console.log('向下滚动')
}else{
console.log('向上滚动')
}
}
2> 属性:
属性 | 详解 |
---|---|
altKey | 按下alt的同时触发 |
ctrlKey | 按下CTRL的同时触发 |
metaKey | 按下meta键的同时触发 |
shiftKey | 按下shift键的同时触发 |
clientX | 相对浏览器左上角的水平坐标 |
clientY | 相对浏览器左上角的垂直坐标 |
offsetX | 相对于事件源左上角水平偏移 |
offsetY | 相对于事件源左上角垂直偏移 |
pageX | 相对于document左上角的水平坐标 |
pageY | 相对于document左上角的垂直坐标 |
screenX | 相对于屏幕左上角的水平坐标 |
screenY | 相对于屏幕左上角的垂直坐标 |
movementX | 相对于前一次事件中screenX的偏移 |
movementY | 相对于前一次事件中screenY的偏移 |
layerX | 相对于offsetParent左上角的水平偏移 |
layerY | 相对于offsetParent左上角的垂直偏移 |
button | 0,1,2 -> 0代表鼠标的左键,1代表滑轮,2代表右键 |
target | 指向 |
举例:
//altkey、shiftkey
box.onclick = function (e) {
console.log(e);
if( e.altKey === true && e.shiftKey === true ){
this.style.backgroundColor = 'purple';
// console.log(box)
}else{
console.log('左击了盒子');
}
};
//altkey、target
box.onclick = e => {
console.log(e);
if( e.altKey === true ){
e.target.style.backgroundColor = 'pink';
}else{
e.target.style.backgroundColor = '#58a';
}
};
//button
box.onmousedown = e => {
e.stopPropagation();
e.button === 0 ? console.log('左击') : ( e.button === 1 ? console.log('滚轮') : console.log('右击') );
};
八、移动端专属事件
在手机移动端:TouchEvent
是触摸事件对象 changedTouches
事件 | 何时触发 |
---|---|
touchstart | 手按下 |
touchmove | 滑动 |
ontouchend | 当触摸结束 |
touchcancel | 触摸被意外终止 |
box.ontouchstart = e => {//手机按下的那一刻
console.log("anxia");
}
box.ontouchmove = function (e) {//手指在整个页面里边滑动length表示几根手指
console.log("滑动")
}
box.ontouchend = e => {//手机按下的那一刻
console.log(e)
}
box.ontouchcancel = e => {
console.log('手指意外离开了')
}
九、键盘事件
事件 | 何时触发 |
---|---|
keydown | 键盘按下 |
keyup | 键盘抬起 |
keypress | 键盘按下 |
关于复制粘贴:(不好用,建议用cliboard.js)
ClipboardEvent{
target: 内容是从那个元素里边复制过来的,
type: 'copy', 复制类型
clipboardData: {被复制的东西
files: 文件
items: 除了文件之外的东西
}
}
getData('什么类型的数据')
属性 | 解释 |
---|---|
key | 按下去的是哪一个键 |
keyCode | 键码(键盘上的每一个键都有一个键码) |
//keydown
//(组合键:(功能键+非功能键) 用keydown来做)
//功能键:shift、alt、ctrl等
document.addEventListener( 'keydown', e => {
console.log('keydown:', e)
if( e.altKey === true && e.key === 'a' ){
alert('此组合不存在');
}
} )
//keyup
document.addEventListener( 'keyup', e => {
console.log('keyup:', e)
} )
//keypress
document.addEventListener( 'keypress', e => {
sconsole.log('keypress:', e)
} )
十、ui事件
浏览器加载顺序:
html
—>css
—>js
–>图片、视频、音频
事件 | |
---|---|
load | 监听事件是否加载完成(window, document,img,video,audio) |
ready | 监听页面是否加载完成(window, document,img,video,audio) |
error | 监听页面是否出错 |
const img = document.querySelector('img');
window.addEventListener( 'load', e => {
console.log('window加载完毕')
} )
img.addEventListener( 'load', e => {//img标签的外部资源加载完成
console.log('img加载完毕')
} )
img.onerror = function (e) {
console.log('图片加载失败')
}
十一、事件委托
起源:
每个一个元素都绑定一个点击,获取鼠标的其他事件。首先找到每一个元素,给他们的某个属性赋值,为一个函数(对象),对象是最占内存的数据类型,对象越多,占用的内存越多,有可能卡顿。
尽可能减少给每个元素单独绑事件:事件委托
**原理:**事件冒泡
<body>
<div class="container">
<div class="card1"></div>
<div class="card2"></div>
<div class="card3"></div>
</div>
</body>
<script>
const container = document.querySelector('.container');
container.addEventListener('click', e => {
e.stopPropagation();
const target = e.target.className;//根据类名来判断我点了哪一个标签,做不同的事情
switch( target ){
case 'card1':
console.log("我是card1");
break;
case 'card2':
console.log('我是card2');
break;
default:
console.log("我是container")
}
})
</script>
ript>
const container = document.querySelector(‘.container’);
container.addEventListener(‘click’, e => {
e.stopPropagation();
const target = e.target.className;//根据类名来判断我点了哪一个标签,做不同的事情
switch( target ){
case ‘card1’:
console.log(“我是card1”);
break;
case ‘card2’:
console.log(‘我是card2’);
break;
default:
console.log(“我是container”)
}
})