一、事宜简述
1、事宜观点
在Web中, 事宜在浏览器窗口中被触发,实行事前绑定的事宜处置惩罚器(也就是事宜触发时会运转的代码块),对事宜做出相应。
用户在浏览器的任何一个操纵都邑去触发一个事宜,JavaScript采纳异步事宜驱动编程模子,当文档、浏览器、元素或与之相干对象发作特定事变时,浏览器会发生事宜。
2、罕见的事宜
事宜是某个行动或许触发,比方点击、鼠标挪动、提交表单,转动菜单等等
二、事宜流
1、事宜流的作用
事宜流形貌的是从页面中吸收事宜的递次,比方有两个嵌套的div,点击了内层的div,这时候是内层的div先触发click事宜照样外层先触发?
假如事宜不流传,我们没法肯定我们点击的对象是什么?
2、事宜流三种模子
- 2.1事宜冒泡模子
事宜最先时由最详细的元素吸收,然后逐级向上流传到较为不详细的元素。比方点击div时,起首是div先监听到了点击事宜,然后向上流传到body/html/document
- 2.2事宜捕捉模子
和事宜冒泡相反,事宜最最先由最外层不太详细的节点先监听到,然后向下通报到最详细的元素。
比方点击div事宜,先是document监听到,然后分发到html/body/div
- 2.3DOM事宜流
DOM2级事宜划定事宜流包括三个阶段,起首发作的是事宜捕捉,为截取事宜供应时机,然后是现实目的吸收事宜,末了是冒泡阶段
- 事宜捕捉阶段
- 处于目的阶段
- 事宜冒泡阶段
3、用代码演示dom事宜流
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
<style>
.box1{
border:1px solid black;
padding:10px;
}
</style>
</head>
<body>
<div class="container box1">
container
<div class="box box1">
box
<div class="target box1">target</div>
</div>
</div>
</body>
<script>
var container= document.querySelector('.container')
var box= document.querySelector('.box')
var target=document.querySelector('.target')
target.addEventListener('click',function(){
console.log('target in 捕捉')
},true)
box.addEventListener('click',function(){
console.log('box in 捕捉')
},true)
container.addEventListener('click',function(){
console.log('container in 捕捉')
},true)
target.addEventListener('click',function(){
console.log('target in 冒泡')
},false)
box.addEventListener('click',function(){
console.log('box in 冒泡')
},false)
container.addEventListener('click',function(){
console.log('container in 冒泡')
},false)
</script>
</html>
实行效果:
![图片上传中…]
三、事宜处置惩罚顺序(事宜侦听器(listener))
1、观点
事宜处置惩罚顺序:事宜触发后,实行相应对应事宜的顺序。
事宜处置惩罚顺序是预先设定的,我们须要提早定义好某些事宜发作了该怎样处置惩罚,这个历程叫做绑定事宜处置惩罚顺序
2、JavaScript指定事宜处置惩罚顺序
2.1道理:
JavaScript指定事宜处置惩罚顺序就是把一个函数赋值给一个元素的事宜处置惩罚顺序属性(如onclick)
2.2绑定的历程:
选中元素,选中事宜处置惩罚顺序属性如onclick,给属性赋值一个处置惩罚函数。
<input id="btnClick" type="button" value="Click Here" />
<script >
var btnClick = document.getElementById('btnClick');
btnClick.onclick = function showMessage() {
alert(this.id);
};
</script>
2.3不足:
不能给同一个元素的同一个事宜处置惩罚顺序属性绑定多个事宜处置惩罚函数,会发生掩盖的。
3、DOM2事宜处置惩罚顺序
3.1简介
DOM2事宜处置惩罚顺序能够处理不能绑定多个事宜处置惩罚函数的题目
DOM2级事宜定义了两个要领用于处置惩罚指定和删除事宜处置惩罚顺序的操纵:
- addEventListener
- removeEventListener
3.2 addEventListener运用
addEventListener有三个参数
- 事宜范例
- 事宜处置惩罚要领
- 布尔参数,假如是true示意在捕捉阶段挪用事宜处置惩罚顺序,假如是false,则是在事宜冒泡阶段处置惩罚。默许时false,没有特别需求,第三个参数能够不写
3.3举个栗子
<input id="btnClick" type="button" value="Click Here" />
<script >
var btnClick = document.getElementById('btnClick');
btnClick.addEventListener('click', function() {
alert(this.id);
}, false);
</script>
总结:addEventListener 和制订事宜处置惩罚顺序的差别,一个是对属性赋值,别的一个addEventListener是实行一个函数,能够屡次实行
3.4 removeEventListener解绑事宜
经由过程addEventListener增加的事宜处置惩罚顺序只能经由过程removeEventListener移除,移除时参数与增加的时候雷同
增加的匿名函数没法移除
<input id="btnClick" type="button" value="Click Here" />
<script >
var btnClick = document.getElementById('btnClick')
var handler=function() {
console.log("hhhhhhhhh")
}
btnClick.addEventListener('click', handler, false)
btnClick.removeEventListener('click', handler, false)
</script>
四、事宜对象
1、事宜对象的泉源
在触发DOM上的某个事宜的时候会发生一个事宜对象event,这个对象包括着一切与事宜有关的信息,包括发生事宜的元素、事宜范例等相干信息。
2、event的罕见属性
event对象包括与建立它的特定事宜有关的属性和要领,触发事宜的范例差别,可用的属性和要领也差别,然则一切事宜都邑包括
2.1bubbles:
默许为false,示意事宜对象是不是冒泡。
假如该属性为false,div.addEventListener要领在冒泡阶段监听不会触发。只能写成div.addEventListener(‘click’, callback, true)在“捕捉阶段”监听这个事宜。
2.2cancelable:
默许为false,示意事宜是不是能够被作废.只有为true的时候,才用Event.preventDefault()作废这个事宜。
2.3preventDefault
阻挠默许事宜
<a href="http://baid.com">baidu</a>
<script>
document.querySelector('a').onclick= function(e){
e.preventDefault()
console.log(this.href)
if(/baidu.com/.test(this.href)){
location.href = this.href
}
}
</script>
<form action="/login">
<input type="text" name="username">
<input type="submit">
</form>
<script>
document.querySelector('form').addEventListener('submit',function(e){
e.preventDefault()
if(document.querySelector('input[name=username]').value==='sjz'){
this.submit()
}
})
</script>
2.4target和currenttarget
在事宜处置惩罚顺序内部,this一直等同于currentTarget,currentTarget为绑定事宜的元素,而target是为触发事宜的现实目的。
当存在嵌套的时候,二者不一样,详细概况能够见这篇文章链接形貌,或许中文版event.target 和 event.currentTarget。我这里不做赘述
2.5stopPropagation()
阻挠事宜在 DOM 中继续流传,防备再触发定义在别的节点上的监听函数,然则不包括在当前节点上其他的事宜监听函数。
举个栗子
<style>
.container,
.box,
.target{
border: 1px solid;
padding: 10px;
}
</style>
<button id="btn">click</button>
<div class="container">
container
<div class="box">
box
<div class="target">target</div>
</div>
</div>
<script>
function $(selector){
return document.querySelector(selector)
}
var btn = $('#btn')
btn.onclick = function (e){
console.log(e)
}
btn.addEventListener('click', function(evt){
console.log(this)
console.log(btn)
console.log(evt.target)
})
$('.container').addEventListener('click', function(e){
console.log('contianer click.. in 捕捉阶段')
}, true)
$('.box').addEventListener('click', function(e){
//e.stopPropagation()
console.log('box click.. in 捕捉阶段')
}, true)
$('.target').addEventListener('click', function(e){
console.log('target click.. in 捕捉阶段')
}, true)
$('.container').addEventListener('click', function(e){
console.log('contianer click.. in 冒泡阶段')
}, false)
$('.box').addEventListener('click', function(e){
//e.stopPropagation()
console.log('box click.. in 冒泡阶段')
}, false)
$('.target').addEventListener('click', function(e){
console.log('target click.. in 冒泡阶段')
}, false)
</script>
效果
没有给捕捉阶段的box加e.stopPropagation()的效果
给捕捉阶段的box加e.stopPropagation()以后的效果
五、阻挠事宜代办
哈哈哈写事宜代办前,找到了这篇事宜代办的文章用例子诠释事宜模子和事宜代办,这里写事宜模子的汗青也写得相称棒,所以先就转载过来了。
1、事宜代办的道理:
应用事宜模子的流传性子,将子元素的监听函数绑定到父元素上,经由过程事宜流传去实行监听函数。
2、举个栗子
需求:给container内里一切box都绑定点击事宜,点击时输出box的值
2.1体式格局一:foreach
道理:选中.box一切元素,获得一个类数组对象,遍历这个类数组对象,给.box元素逐一绑click事宜。
代码:
<div class="container">
<div class="box">box1</div>
<div class="box">box2</div>
<div class="box">box3</div>
</div>
<script>
function $(selector){
return document.querySelector(selector)
}
function $$(selector){
return document.querySelectorAll(selector)
}
// $$('.box').forEach(function(node){
// node.onclick = function(){
// console.log(this.innerText)
// }
// })
效果
瑕玷:实行foreach选中的box时牢固的,假如我们后续再加上几个box,后加的box就没有绑定上点击事宜。
代码链接
2.2体式格局二事宜代办
道理:给container绑定点击事宜,经由过程e.target猎取点击事宜目的
代码:
<div class="container">
<div class="box">box1</div>
<div class="box">box2</div>
<div class="box">box3</div>
</div>
<button id="add">add</button>
<script>
function $(selector){
return document.querySelector(selector)
}
function $$(selector){
return document.querySelectorAll(selector)
}
$('.container').onclick = function(e){
console.log(this)
console.log(e.target)
if(e.target.classList.contains('box')){//contain少写s
console.log(e.target.innerText)
}
}
var i = 4
$('#add').onclick = function(){
var box = document.createElement('div')
box.classList.add('box')
box.innerText = 'box' + (i++)
$('.container').appendChild(box)//box加''
}
遇坑:
1、contain少写s
- 2、appendChild(‘box’)//box加”是错的,box自身是变量
六、罕见的事宜范例
罕见事宜范例 | 剖析 |
---|---|
click | 单击 |
dblclick | 双击 |
focus | 核心,比方表单input把光标放上去最先输入的时候 |
blur | 落空核心,比方输入完成切换到下一个输入框时,就落空了核心 |
keyup | 按键按下松开的时候触发, |
change | 比方input落空核心而且值发作了转变 |
submit | 表单提交的时候触发 |
scroll | 页面转动的时候触发,注重运用函数撙节 |
resize | 页面面积变化触发,注重运用函数撙节 |
DOMContentLoaded | DOM 构造剖析完成,不必等图片剖析 |
load | 页面一切资本(图片css 等)加载完成触发,触发时间比较晚 |
mouseover | 鼠标放上去触发,注重进入元素的子元素会反复触发 |
mouseout | 鼠标拿出去触发,注重脱离元素的子元素会反复触发 |
mouseenter | 鼠标进入触发,进入子元素不会触发,比较经常使用 |
mouseleave | 鼠标脱离触发,脱离子元素不会触发,比较经常使用 |
演示代码:直接复制代码到编辑器,在浏览器去测试这些事宜
或许点击这个链接测试
<button id="btn">点我</button>
<button id="btn1">点我1</button>
<div class="ct" style="font-size: 20px">
<div class="box">hello</div>
</div>
<div class="ct1">
<div class="box1"></div>
</div>
<input id="input-name" type="text">
<form id="form" action="/upload">
<input id="username" name="username" type="text">
<p class="msg"></p>
<input id="btn-submit" type="submit" value="注册">
</form>
<img src="https://jirengu.com/data/upload/2017/0118/17/587f39fba695a.png" alt="">
<script>
function $(selector){
return document.querySelector(selector);
}
$('#btn').addEventListener('click', function(){
console.log('click')
console.log(this)
})
$('#btn1').addEventListener('dblclick', function(){
console.log('dblclick')
console.log(this)
})
$('.ct').addEventListener('mouseover', function(){
console.log('mouseover')
console.log(this)
// this.style.borderColor = 'blue'
this.classList.add('hover')
})
$('.ct').addEventListener('mouseout', function(){
console.log('mouseout...')
// this.style.borderColor = 'red'
this.classList.remove('hover')
})
$('.ct1').addEventListener('mouseenter', function(){
console.log('mouseenter...')
//this.style.borderColor = 'blue'
this.classList.add('hover')
})
$('.ct1').addEventListener('mouseleave', function(){
console.log('mouseleave...')
//this.style.borderColor = 'blue'
this.classList.remove('hover')
})
$('#input-name').addEventListener('focus', function(){
console.log('focus...')
console.log(this.value)
})
$('#input-name').addEventListener('blur', function(){
console.log('blur...')
console.log(this.value)
})
$('#input-name').addEventListener('keyup', function(e){
console.log('keyup...')
console.log(this.value)
console.log(e)
this.value = this.value.toUpperCase()
})
$('#input-name').addEventListener('change', function(e){
console.log('change...')
console.log(this.value)
console.log(e)
this.value = this.value.toUpperCase()
})
$('#form').addEventListener('submit', function(e){
e.preventDefault();
if(/^\w{6,12}$/.test($('#username').value)){
$('#form').submit();
}else{
$('#form .msg').innerText = '出错了'
$('#form .msg').style.display = 'block'
console.log(' no submit...');
}
})
window.addEventListener('scroll', function(e){
console.log('scroll..')
})
window.addEventListener('resize', function(e){
console.log('resize..')
})
//页面一切资本加载完成
window.onload = function(){
console.log('window loaded')
}
//DOM 构造剖析完成
document.addEventListener('DOMContentLoaded', function(){
console.log('DOMContentLoaded ')
})
console.log($('img').width) //0
$('img').onload = function(){
console.log(this.width) //此时才获得图片的实在大小
}
</script>
<style>
body{
color: blue;
}
.ct,.ct1{
width: 100px;
height: 100px;
border: 1px solid red;
background-color: yellow;
margin: 20px;
}
.box,.box1{
width: 50px;
height: 50px;
background-color: blue;
}
.ct.hover, .ct1.hover{
border-color: blue;
background-color: pink;
}
.box3{
list-style: none;
background: yellow;
margin: 0;
padding: 0;
}
.box3>li{
background: pink;
margin: 5px;
padding: 10px;
}
.box3>li.hover{
background-color: blue;
}
.msg{
display: none;
}
</style>
七、自定义事宜
var EventCenter = {
on: function(type, handler){
document.addEventListener(type, handler)
},
fire: function(type, data){
return document.dispatchEvent(new CustomEvent(type, {
detail: data
}))
}
}
EventCenter.on('hello', function(e){
console.log(e.detail)
})
EventCenter.fire('hello', '你好')