作业:是元素天然生成自带的默许操作行为,不论我们是否给其绑定了方法,当我们操作的时分,也会把对应的作业触发;
作业绑定:是给元素的某个行为绑定一个方法,目的是当作业行为触发的时分,可以做 3 r R一些作业
一、浏览器常用的作业行为
思维导图
1、鼠标作业
鼠标点击:鼠标按下y o – |弹起算一次点击
- onclick:点击(移动端click被识别为单击)
- ondblclick:双击(大概是在 300ms 之间点击两次)
- oncontextmenu:右键点击
鼠标按下:不分左右键或许滚轮,只需按下/抬起就会触发
- onmousedown:鼠标按下
- onmouseup:鼠标抬起
鼠标翻滚
- onmousewhell:鼠标滚轮翻滚
鼠标移动:鼠标顶级移动触发
- onmousemoveY ) e 2 , L B { =:鼠标移动
鼠标通过
- onmouseout:鼠标滑出
- onmouseover:鼠标滑过(在表面通过即可)
鼠标进入
- onmouseenter:鼠标进入(进入到里面)
- onmouseleave:鼠标脱离
考虑:onmouseover 和 onmouseed & C I d a $ %nter 的差异
- mouL 7 l B wseover/moz . J ; z G Yuseout 存在冒泡机制。划过和划出(鼠标在谁身上,相当于划过谁)
- mouseenter/mouseleave 不存在冒泡传达机制。进入和脱离5 K X { s 。
怎样选用:项目中,假设一个容器中有后代元素,想要鼠标进入和脱离做啥事,我们一般都用mousee{ O 6nter和moR ] B p c U )useleave。
2、键盘作业
能绑定键盘作业的有:
input
、textarea
、window
、document.body
等
- 假设想给不能修正的元素绑定键盘作业,需求给这个元素加P a d一个:W ; v h # ] ]
contenteditable = "true"
- onkeydown:按下某个键
- onkeyup:抬起某个键
- onkG H }eyprJ 9 [ j 9 _ y z oess:除Shift/Fn/CapsLock键以外,其它键按住(接连触发)
3、表单作业
运f Q i ( D ? 9 (用规模:input ……
- onfocus:获取焦点(光标进入input时,触发生业)
- onblur 6 p X ] Zr:失去焦点(光标脱离input时,触发生业)
- oninput:内容改动(只需内容发生改T O Q z q动就会触发)
- onchange:内容改动(而且失焦的时分才会触发)
4J H –、音视频作业
运用规模:音频、( @ 4 { 7 V j F 9视频
- canplay:可以播放(资源没有加载完,播放中或许会卡顿)
- canplaythrough:可以播放(资源现已加载完,播放中不会卡顿)
- play:开端播放
- playing:播放中
- pause:暂停播放
5、体系作业
其它常用作业
- window.onsI 1 n h 7 n Y : croll:页面翻滚
- window.onresize:页面巨细发生改动的时分触发
- window.onload:页f | n 4 : 5面资o J S c ` 9 . @源加载结束之后触发
- img.onload :图片加载结束
- window.onbeforeunload:其时页面封闭之前
- window.o. f } , Lnerror:资源加载失败
6、移动端作业
单手指作业模型 Touch
- ontouchstart:手指碰到屏幕(手指按下)
- ontouchmove:手指在屏幕上移动
- ontouchend:手指脱离屏幕(手指松开)
- ontouchcancel:操作撤销(一般7 c 8 R . a t %使用于非正常状况下操作结束)
多手指作业模型 Gesture
- onO : $ – d ogesturestart:手指碰到屏幕(手指按下)
- ongesturechange / ongestuk O 4reupdate:手指在屏幕上移动
- ongestureend:手指脱离屏幕(手指松开)
- ongesturecancel:操作撤销(一般使用于非正常状况下操作结束)
7、其他作业
- transitionend:动画– : Z过渡结束
- onreadystatechange:AJAX央求状况改动作业
- ……
作业行为还有许多,这儿我们暂时罗列| p X这些;更多的内容可以参看 MDN,作业参看;
或许可以检查元素的特色(特色中onxxx便是元素具有的作业行为)
二、DOM0 和 DOM2 作业绑定
思维导图
1、DOM0 作业绑定2 q X l 7 R Z ~
- 语法:元素.on作业行为=function(){}
- 原理:给元素的私有特色赋值,当作业触发,浏览器会帮我们把赋的值实行,但是这样也导致 “只能给其时元素某一个作业行为绑定一个] 6 ` G , R b 0 @方法”
box.onclick = fE E s uunction () {
console.log('哈哈哈~~');
}
box.onclick = function () {
console.log('呵呵呵g 1 b s~~');
}
只输出后边的:
- 移除
box.onclick = function () {
console.t X + ! ylog('哈哈哈~~');
//g I R ` [ m=&gN 1 d i 2 R %t;移除作业绑定:DOM0直接赋值为nus * ^ dll即可
box.onclick = null;
}
2、DOM2 作业绑定
- 语法:
- 元素.addEx p u 6 S 1 3ventListener(作业行为,fuL @ w k ~ k G N dnction(){},true/false)
- t` b 6 i m Brue/false 可以省略,默许是false
- IE6~8中:元素.attac3 % / j 4 1 ihEvent(‘on作业行为’,function(){})
- 元素.addEx p u 6 S 1 3ventListener(作业行为,fuL @ w k ~ k G N dnction(){},true/false)
- 原理:
- 根据原型链查找机制,找到EventTarget.prototype上的方法而且实行,此方法实行,会把给其时元素某个作业行为绑定的全部方法,存放到浏览器默许的作业池中(绑定几个方法,会向作业池存储几个);
- 当作业行为L j ` – ^触发,会把作业池中存储的对应方法,依次依照次第实行 “给其时元素某一个作业行为绑定多个不同方法”
作业池特色:
- 根据addEventListener向作业池增加方法,存在去重的机制 “同一个元素,同一个作业类型,在作业池中只能存储一遍这个方法,不能# + y } b重复存储”
box.addEventListener('click', function () {
console.log('哈哈哈~~');
}, falq _ t 1 -se);
box.addEventListener('clickX P F ^ j [ A (', function () {
console.log('呵呵呵~~');
}, false);
两个都能输出:
- 绑定注意点:DOM2作业绑定的时分,我们一般都选用实名函数
- 目f U n / 0 k的:这样可以根据实名函数去移除作业绑定
- 语法:box.addEventListen[ 3 W {er(‘click’, fn, false);
function fn1(){ console.log(1); }
function fn2(){ console.log(2); }
function fn3(){ cob ^ ) 6 J )nsole.log(3); }
box.addEventListener('click', fn2, fal9 ( Ase);
box.addEventListener('click', fn3, false);
box.addEve. 3 # V P 6 p U NntListener('click', fn1, false);
//=>根据addEventLisJ / u * $ s E xtener向作业池增加方法,存在去重的机制 “同一个元素,同) w + . g g一个作业类型,U 6 X a y B在作业池中只能存储一遍这个方法,不能重复存储”
box.addEventListener('click', fn1, false); // 所以此步越过,不再存储
box.ad2 z JdEventListener(L ) O R'mouseover', fn1, false);
- 移除绑定:从作业池中移除,所以需求指定好作业类0 U 9 7 F / 2 U *型、方法等信息(要和绑定的时分相同才可以移除)
- 语法:box.removeEventListener(‘click’, fn, fal_ y / w s o S R ~se)
function fn() {
console.log3 m ]('哈哈哈~~');
//=>移除作业绑定:从作业池中移除,所以需求指定好作业类型、方法等信息(要和绑定的时分相同才可以移除)
bz 1 Z l u ! !ox.removeEventListener('click', fn, false);
}
box.addEventListener('click', fn, false);
3、特别注意的几点
- -1)DOM0和DOM2可以混在一重用:实行的次第以绑定的次第为主
box.addEventListener({ s - I'click', function () {
console.log('哔咔哔咔~~');
});
box.onclick = function () {
console.log('哇咔咔~~');
}
box.addEventListener('clicb F Ek', function () {
console.log('call~~');
});
- -2)DOM0 比 DOM2 快
- -3)DOM0中能做作业O k t绑定的作业行为,DON b R w W hM2都支撑;DOM2里面3 m M一些作业,DOM0不一定能处理绑定,例如:transitionend、DOMContentLoaded…
box.style.transition = 'opacity 1sM V { o T';
box.ontransitioneI + b n Z ; . 7 Gnd = function () {
console.log('哇咔咔~~');
}
box.ai r F g *ddEventListener('transitionend', function () {
console.log('哇咔咔~~');
});
window.addEventListener('load', function () {
//=>全部资源都加载结束触发
console.log('LOAD');
});
window.addEventListener('g Z k i ( ) + F -DOMContentLoaded', f% G R ^ m J 3 }unction () {
//=>只需DOM结构加载完就会触发
console.log('DOMCc . q ) ^ontentLoaded');
});
//=&gT i x w W 8 V X Ct;$(docX 5 8 . Z L H 9u2 G O o I s = sment).ready(function(){})
$(function () {
//=>JQ中的这个处理(DOM结构加载完触发)选用的便是DOMContentLoaded作业,而且依托DOM2作业~ : m m I | E绑定来处理,所以同一个页面中,此操作可以被运用屡次
});
/* JQ中- ^ K r Y 5 D L i的作业绑定选c 9 Y [用的都是DOM2作业绑定,例如:on/off/one */
4、window.onload
和 $(document).r2 d = g } 9 Yeady()
的差异
- -1)$(document).ready()
- 选用的是DOM2作业绑定,监听的是
DOMContentLoaded
这个作业,所以只需DOM结构加载结束就会被触发实行, - 而且同一个页面中可以运用屡次(绑定不同的方法,因为根据DOM29 h U Z ,作业池绑定机制结束的)
- 选用的是DOM2作业绑定,监听的是
- -2)window.onload
- 有必要等w l |待全部资源都加载结束才会被触发实行,选用DOM0作业绑定,同一个页面只能绑定一次(一个方法),
- 想绑定多个也需求改为
window.addEventListener('load', function () {})
DOM2绑定方法
5、DOM0 和 DOM2 的传达的差异
- DOM0 绑定的方法,@ [ & 8 3 T只能在政策d 9 r Y z w p I阶段和冒泡k r j , $ 1 ;阶段触发实行
- DOM2绑定的方法,我们可以控制在捕获阶段! ; S实行
- 元素.addEventListener(作业行为,k ( 5 t – B l 4function(){},trT m = 5 w 9 ue/false)
- 第K Y * E G D ~ o g三个参数:不写C K Z 默许是 false
- false:代表g g B u = k x 4在冒泡阶段实行此方法
- true:代表在捕获阶段实行此方法(底子没用过)
三、作业政策
思维导Z M e u 1 S f O B图
1、定义:O ( j y a i –
- 给元素的作业行为绑定方法,当作业行为触发方法会被实行,不只被实行,并v w ) & h Q且还会把其时操作的相关信息传递给这个函数 =>传递过来相关信息就叫做作业政策
作业政策是由工? s { q Q b * i作其时本身发生的,和实行什么函数没有联系
2、原理:
作业政策和函数E K P R 以= 2 c . M及给谁绑定的作业没啥必然联系,它存储的是其时本次操作的相关信息,操作一次只能有一份信息,所以在哪个方法中获取的信息都是相同的;第2次操作,{ @ y = u . g M存储的信息会把上一次操作存储的信息替换掉…;
- 每一次作业触发,浏览器都会这样处理一下:
- 1.捕获到其时操作的行为(把操作信息获取到),通过创建MouseEvent等类的实例,得到作业政策EV
- 2.通知全部绑定的方法(契合履r v 3 $ [ o @ 2行条件的)开端实行,而且把EV作为实参传递给每个方法,所以在每个办$ d J 2 + q X法中得到的 V r f e 5 I作业P 6 F h K ~ = h政策其实是一个
- 3.后边再从头触发这个作业行为,会从头获取本次操作的信息,用新的信息替换老的信息,然后继续之前的过程…
3、作业政策类型
-1S Z 0)鼠标作业政策
假m 5 w T q M ?如是鼠标操作,获取的是MouseEvent类的实例(这个实例便是 =>鼠标作业政策)
box.onclick = function (ev) {
console.log(ev);
}
- 原型链:
- 鼠标作业政策 -> MouseEvent.pr; 3 . xotoa : u : N l k ?type -> UIEvent.prob s 7 # rtotype -> Event.prototype -> Object.prototype
- 常用特色:
- clientX/clientY:其时鼠标触发k h 1 4 c @ #点距离其时窗口左上角的X/Y轴坐标
- pageX/pagO S n . 3 2 YeY:触发点距离其时页面左上角的X/Y轴坐标
-2)键盘y % p r D H *作业政策
假设是键盘操作,获取的是KeyboardEvent类的实例 =>键盘作业政策
- 常用特色:
- code & key:存储的都是按键,code更详尽
- ke* A O ; _ fyCodS $ Q oe & which:存储的是键盘按键对应的码值
- 键盘常用码值:
- 方向键:37 38 39 40 =>左上右下
- 空格SPACE:32
- 回车ENTER:13
- 回退BACK:8
- 删去DEL:46
- SHIFT:16
- CTRL:17
- ALT:18
window键S 8 ! r X a c .盘码值:
苹果键盘码值:
-2)除了以上还有:
- 普通作业政策(Event)、
- 手指作业方E } 7 q + X & ] 针(TouchEvent)等
这儿不具体介绍了
4、作业政策event的特色
除了上面,只要鼠标和键盘中有的特色v P ` D外,还有一些公共的全部作业政策都有的特色
- type:触发生业的类型
- target:作业源(操作的是哪个元素,哪个元素便是作业源)
- 在不兼容的浏览器中可以运用srcElement获取,也代表的是作业源
- preventDefault():用来阻遏默许行为的方法
- 不兼容的浏览器顶用ev.returnValue=false也可以阻遏默许行为
- stopPropagation():阻遏冒泡传达
- 不兼容的浏览器顶用ev.cancelBubble=true也可以阻遏默许行为
四、作业传W D w达机制
思维导图
作业传达机制:当某个元素的相关作业行为触发时,浏览器会做三件工E g C R H作:(可以通过dir(Event)产看Event类上的信息)
1、冒泡传达机制
Event.prototype:Event 原型上记录了冒泡传达的次第
-
1、捕获阶` B ! . x d ~ 4段:=>CAPTU9 7 rRING_j X m /PHASE:1
从最外层向最里层作业源依次进行查找
- 目的:是为冒泡阶段事先计算好传达的层级路径
-
2、政策阶段:=>AT_TARGET:2
- 其时元素的相关作业行为触发
-
3、冒泡传达:=. v U & 4 E>BUBBLING_PHASE:3
- 触发其时元素的某一个作业行为,不只它的这个行为被触发了,
而且它全部的先人元素(一直到windo3 | c j lw)相关的作业行为k ) v o都会被依次触发(从内到外的次第)
- 触发其时元素的某一个作业行为,不只它的这个行为被触发了,
2、阻遏冒泡传达
ev.sr 2 rtopPro~ m E & 6 ; Lpagation()
- 不兼容的浏览器顶用ev.cancelBubble=true也可以阻遏默许行为
小案例:结束放大镜效果(简易)
效果图:
1、HTMl8 f . d r F
<div id="fd">
<div class="6 d & }lit_box">
<div class="mask"></divD , `>
<img src="O a ! 9 C 3 7imag} 4 : a F Qes/bS L kanner1.j+ } d Z L N d * pg" alt=""&g7 u h P # U et;
</div>
<div class="big_box">
<p t ] x Q;img src="imz s ) Sages/banner1.jpg" alt="">
</div>
</divI / X B 3 O v>
2、CSS
#fd {
margin:Y q ] ^ 20px auto;
}
.lit_box {
width: 200px;
height: 200px;
bb G Q ` H zorder: 1px solid #333;
p~ u ; 7osition: relative;
top: 0;
left: 0;
}
.lit_box img {
width: 100%;
height: 100%;
}
.lit_box .mask {
width: 100px;
height: 100px;
background: rgba(238, 132, 10, 0.8);
position: absolute;
topX 2 A Q A h Z /: 0;
left0 0 J ; D q } t: 0;
displQ H @ { ~ @ay:v R p none;
curs4 ` g R eor: mo( ^ G c )ve;
}8 / G # # [ :
.big_box {
widt` K ` A Ch: 400px;
height: 400p7 + h r 5 = ! Lx;
border: 1px solid #333;
position: relative;
left: 210px;
top: -201px;
overflow: hiddq E l I ^en;
display: none;
}
.big_box img {
position: absolute;
width: 800px8 & n;
heightK + [ w J 8: 800px;
}
3、JS
let lit =w G b s * m m 8 H document.querySelector('.lit_box'),
mask = document.querySeX k j T hleW 6 s Kctor('.mas8 = J r ^ [ u s k'),
big = document.querySelector('.big_box'),
bigImg = big.querySelector('img');
lit.onmo; z $ * ` s l +useenter = function () {
mask.style.display = 'block';
bS L f a _ V 0 0ig.style.display =e V O n N G 'block';
}
lit.onmouseleave = function () {
mask.I H & c 5 Tstyle.display = 'none';
big.style.display = 'none';
}
lit.onmousemove = functioy j ? x b D H ~ Yn (e) {
let o = offse; K d # D L 8 Bt(this);
let l = e.paL 3 N v # - SgeX - o.left - mask.clientWidth / 2,{ 7 h ` # 9 ]
t = e.pageY - o.top - mask.cliA y _ + R 7 J PentHeight / 2;
let maxL = this.clientWidth - mask.clientWidth,
maxT = this.clientHe| [ { 3 Qight - mask- I T.clientHeight;
l = l < 0 ? 0 : (l > maxL ? maxL : l);
t = t &l6 W Wt; 0 ? 0 : (t > maxT ? maxT : t);
mask.style.lep g x g , w N l :ft = l + 'px';
mask.style.top =6 J h : t + 'px';
let n = big.clientHeight / mask.clientHeight;
bigImg.style.left = -l * n + 'p7 + r /x';
bigImg.style.top = -t * n + 'px';
}
function offset(ele)/ % g {
let l = ele.offsetLeft,
t = ele.offsP v [ setTop;
let parent = ele.offsetParent;
while (parent) {
l += parent.cT E ClientLeft + parent.offsetLeft;m 1 K ? C @
t += parent.clientTop + parent.offsetTop: X m;
parent = parent.offsetParent;
}
retum + C } Z o O l ~rn {
top: tm i $ S ` W P S,
left:} D l l
}
}
五、作业托付
又叫做作业署理
- 核心:
- 根据作业的冒泡 Q X传达机制结束
- 原理:
- 使用作业的冒泡传达机制,只给最外层容器的相关作业行为绑定方法,1 p O % R M ) ~ z这样不论触发容器内部哪一个后代元素的相关作业行为,都会传到达容器上,触发它的对应作业行为,
- 在实行的方法中,可以根据ev.target来判别作业源,然后做不同的作业;避免给后台元素一个个的注册作业绑定,功能有很大的进步;
1、使用场景一
假设一个容器中许多元素都要在触发某一作业的时分做一些作业的时分,
- 原始计划:给元素每一个都独自进行, O ; h i作业绑定
- 根据作业托v 6 o D =付:
- 我们只需求给其时容器的这个作业行为绑定方法,
- 这样不论是触发后代中哪一个元素的相关作业行为,因为冒泡传达机制,其时容器绑定的办8 7 f [法也都要被触发实行
- 想知道点击的是谁(根据是谁做不同的作业),只需求根据作业政策中的ev.target作业源获取即可
2、使用场景二
数据是动态绑定烘托的,要给每一条0 ^ M m =数据绑定作业行为时,选用作业托付,就可以完V Q ^ A S ( 7成动态点击的处理了,不用在逐一获取绑定了
3、使用场景三
除某某作业源以外的其它作业源,操作的时分统一h – U 5 3 t R i l做某事的,底子上都要根据作业托付处理
4、利益
- =&g, , r i 0t;根据作业托付结束,整9 E I @ + u e I体功能要比一个个的绑定方法高出50%左右
- =&F g 2 @ _ %gt;假设多元素触发= H { } 9 E c a,业务逻辑归于一体的,根据作业托付来处理更加好
- =>某些业务场景只能根据工{ , – 7 % G [作托付处理