学习周报
JavaScript 事件的更多用法
注册事件
给元素注册事件有两种方式:传统方式和方法监听方式
- 传统方式注册
on开头的事件
特点:注册事件具有唯一性
<body>
<button>传统方法</button>
<script>
let btn = document.querySelector('button');
btn.onclick = function{
alert('1');
}
btn.onclick = function{
alert('2');
}
</script>
</body>
此时只有最后一个处理函数生效,后面的函数会将前面的函数覆盖
2. 监听方法注册事件
2.1 addEvenListener()方法
特点:同一个元素同一个事件可以注册多个监听器,按注册顺序依次执行
使用方法:
eventTarget.addEventListener(type,listener[, useCapture])
方法有三个参数
- type:事件类型字符串,如click、mouseover……,与传统方法区别,这里不带on
- listener:事件处理函数,事件发生时,会调用函数
- useCapture:一个布尔值,当值为true时,进入捕获阶段;当值为false或省略时,进入冒泡阶段
<body>
<button>监听方法注册事件</button>
<script>
let btn = document.querySelector('button');
btn.addEventListener('click',function(){
alert('1');
})
btn.addEventListener('click',function(){
alert('2');
})
</script>
</body>
两个弹窗都能够弹出来
2.2 IE9前 attacEvent()方法
eventTarget.attachEvent (eventNamewithon,callback)
- eventNameWithOn:事件类型字符串,比如onclick、onmouseover,这里要带on
- callback:事件处理函数,当目标触发事件时回调函数被调用
删除事件
- 传统方式注册空事件
element.onclick =null;
执行事件后将事件修改为空
2. 方法监听注册方式
- removeEventListener()方法
eventTarget.removeEventListener(type,listener[, useCapture]);
参数和addEvenListener()方法一致,将listener移除
但此次的listener不能使用匿名函数,因此要在注册事件时同时使用命名函数
<body>
<button>只弹一次</button>
<script>
let btn = document.getElementsByTagName('button');
btn[0].addEventListener('click',fn)
function fn(){
alert('1');
btn[0].removeEventListener('click',fn);
}
</script>
</body>
- IE9前 detachEvent()方法 与removeEventListener()方法用法类似但少最后一个参数
DOM事件流
事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM事件流。
即事件流是事件传播的顺序
DOM事件流有3个阶段:
- 捕获阶段
- 当前目标阶段
- 冒泡阶段
以给div绑定点击事件为例:
事件冒泡:事件开始时由最具体的元素接收,然后逐级向上传播到到DOM最顶层节点的过程。
事件捕获:由DOM最顶层节点开始,然后逐级向下传播到到最具体的元素接收的过程。
- 在实际开发中我们很少关注捕获,一般用冒泡
有些事件是没有冒泡的,比如onblur、onfocus、onmouseenter、onmouseleave
事件对象
- 什么是事件对象
事件对象,可以看作侦听函数里的一个形参,事件对象只有事件存在才会存在,是系统自动创建的,里面包含事件的一系列的数据,如,键盘事件包含用户按下哪一个键
eventTarget.onclick = function (event) { }
eventTarget .addEventListener ( 'click ' , function(event) { })//这个event就是事件对象,我们还喜欢的写成e 或者evt
和事件相关的一系列信息数据集合都放在这个对象里
- 事件对象常见属性和方法
- e.targe 返回的是触发事件的对象(元素)
this返回的是绑定事件的对象(元素)
<body>
<div class="div" style="width: 100px;height: 100px;background: #547;">div</div>
<ul class="ul">
<li>abc</li>
<li>abc</li>
<li>abc</li>
<li>abc</li>
<li>abc</li>
</ul>
<script>
const div = document.querySelector('div');
const ul = document.querySelector('.ul');
div.addEventListener('click',function(e){
console.log(e.target);
console.log(this);
//两个打印出来的结果是一样的
})
ul.addEventListener('click',function(){
console.log(e.target);//this永远指向ul
console.log(this);//当点击li,targe指向li
})
</script>
</body>
- 阻止默认行为
让链接不跳转,或让提交按钮不提交
- preventDefault()方法
<body>
<a href="https://image.baidu.com/" class="a">百度图片</a>
<script>
const a = document.querySelector('a');
a.addEventListener('click',
function(e){
e.preventDefault();
})
</script>
</body>
- 传统方式 利用return false
<body>
<a href="https://image.baidu.com/" class="a">百度图片</a>
<script>
const a = document.querySelector('a');
a.onclick = ()=>{
return false;
}
</script>
</body>
return 后面的代码不再执行
3. 阻止事件冒泡
- 标准写法 stopPropagation()方法
- 低版本浏览器 将cancelBubble属性设置为turn
</head>
<body>
<div class="father">father
<div class="son">son</div>
</div>
<script>
let father = document.querySelector('.father');
let son = father.children[0];
father.addEventListener('click',function(){
alert('father')
})
son.addEventListener('click',function(e){
alert('son');
e.stopPropagation();
e.cancelBubble=true;
})
document.addEventListener('click',function(){
alert('document');
})
</script>
</body>
事件委托
事件委托的原理
不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点。
<body>
<ul>
<li>pink</li>
<li>yellow</li>
<li>blue</li>
<li>red</li>
<li>green</li>
</ul>
<script>
let ul = document.querySelector('ul');
ul.addEventListener('click',function(e){
e.target.style.backgroundColor =e.target.innerHTML
})
</script>
</body>
常用的鼠标事件
- 补充事件
- 禁止鼠标右键菜单
contexmenu用于控制上下文菜单
document.addEventListener ( ' contextmenu ', function(e) {
e.preventDefault ();
})
这样就将右键菜单禁止了
2. 禁止鼠标选中
selectstart开始选中
document.addEventListener ( ' selectstart', function (e) {e.preventDefault ();
})
鼠标事件对象
当事件触发后会产生一个包含一系列信息的集合
实例:
元素跟随鼠标效果
<body>
<div></div>
<script>
let div = document.querySelector('div');
document.addEventListener("mousemove",function(e){
let x= e.pageX;
let y = e.pageY;
div.style.left =x-50 +'px';
div.style.top = y-50 +'px'
})
</script>
</body>
常用的键盘事件
键盘触发的事件
使用addEventListener不需要加on
<body>
<script>
//三个事件的顺序是keydown->keypress->keyup
document.addEventListener('keyup',function(){
console.log('keyup');
})
document.addEventListener('keypress',function(){
console.log('keypress');
})
document.addEventListener('keydown',function(){
console.log('keydown');
})
</script>
</body>
键盘事件对象
- e.key可直接获取键盘按下什么键,区分大小写
- e.code可获取具体按下什么键
以上都存在兼容性 - 兼容性写法e.keyCode,获取按下键的ASCII码
keydown和keyup不区分大小写
keypress区分大小写