click
: 點擊(PC端是點擊,移動端的click表明單擊[移動端使用click會有300ms的延遲])dblclick
: 雙擊mouseover
: 鼠標通過mouseout
:鼠標移出mouseenter
:鼠標進入(沒有冒泡)mouseleave
:鼠標離開(沒有冒泡)mousemove
:鼠標移動mousedown
:鼠標按下(鼠標左右鍵都起做用,按下即觸發,click是按下擡起才觸發,並且先把down和up觸發,才觸發click)mouseup
:鼠標擡起mousewheel
:鼠標滾輪滾動contextmetu
:右鍵上下文菜單keydown
:鍵盤按下(獲取不到最新的value值,只能獲取到上一個)keyup
:鍵盤擡起(能夠獲取到新的value值)keypress
:鍵盤長按(通常不用),和keydown
相似,但keydown
返回的是鍵盤碼,keypress
返回的是ASCII碼input
:移動端的內容改變事件。因爲PC端有物理鍵盤,能夠監聽到鍵盤的按下和擡起,可是移動端時虛擬鍵盤,因此keydown
和keyup
在大部分手機上都沒有,因此使用input
事件統一代替他們input
:當<input>
、<select>
、<textarea>
的值發生變化時觸發// input事件
<textarea id="txt"></textarea>
<span id="span">0字</span>
// js部分
txt.addEventListener('input',function(ev){
span.innerHTML = txt.value.length + '字'
})
複製代碼
focus
:獲取焦點blur
:失去焦點select
:在<input>
、<textarea>
裏面選中文本時觸發。(也有聚焦的功能)// focus事件 select事件
<input type="text" id="txt1"/>
<button id="btn">選中代碼</button>
//js部分
txt1.addEventListener('focus',function(){
console.log(1)
})
// txt1.focus(); //打開頁面自動聚焦
btn.onclick = function(){
txt1.select()
}
複製代碼
change
:事件當<input>
、<select>
、<textarea>
的值發生變化時觸發。
<textarea>
元素的值發生改變,而且喪失焦點時觸發。// change事件
<select name="" id="sele">
<option>哈哈</option>
<option>呵呵</option>
<option>嘿嘿</option>
<option>嘻嘻</option>
</select>
<div id="div">哈哈</div>
//js部分
sele.onchange = function(){
console.log(this.value);
div.innerHTML = this.value;
}
複製代碼
load
:加載完成unload
:在窗口關閉或者document對象將要卸載時觸發beforeunload
:事件在窗口、文檔、各類資源將要卸載前觸發。它能夠用來防止用戶不當心卸載資源scroll
:滾動條滾動事件(頁面必需要有滾動條)mousewheel
:滾動條滾動事件(只要鼠標滾輪就觸發)
ev.wheelDelta
: 能夠檢測滾動的方向
DOMMouseScroll
: 火狐瀏覽器的滾輪滾動事件(只支持DOM2)
ev.detail
: 檢測滾動的方向
resize
:大小改變事件 window.onresize = function(){} 當瀏覽器窗口大小發生改變,會觸發這個事件error
:事件是在頁面或資源加載失敗時觸發hashchange
:事件在 URL 的 hash 部分(即#號後面的部分,包括#號)發生變化時觸發[單手指操做:touch]javascript
touchstart
:手指按下touchmove
:手指移動touchend
:手指離開touchcancel
:由於意外狀況致使手指操做取消 [多手指操做:gesture]gesturestart
:多手指按下gesturechange
:手指改變gestureend
:手指離開canplay
:能夠播放(播放過程當中可能出現因爲資源沒有加載完成致使的卡頓)canplaythrough
:資源加載完成,能夠正常無障礙播放DOMContentLoaded
: DOM加載完成才觸發的事件(高版本支持)readystatechange
: DOM加載完成才觸發的事件(DOM加載完成才觸發的事件)
在低版本IE下,document
有個doScroll
的方法 document.documentElement.doScroll('left')
java
這個方法在DOM沒有加載出來以前是沒有的,也就是說 調用該方法會報錯,換句話來講,只要DOM記載成功 就有doScroll方法chrome
try{
document.documentElement.doScroll('left')
console.log('DOM加載完成');
}catch(e){
再次調用try、catch直到進try
}
複製代碼
/* 在try中包裹可能會報錯的代碼,包裹以後不會影響下面代碼執行 只要捕獲到錯誤,那麼會進catch */
// let a = 5;
try{
console.log(a);
}catch(error){
a = 10;
console.log(error);//字符串
}
alert(a);
複製代碼
可自主擴展其餘事件後端
element.onxxx = function(){}
element.addEventListener('xxx', function(){}, false);
ele.removeEventListener('click', listener, false);
listener
參數若是爲 fn.bind(this)
,則不能移除,由於bind
會改變函數地址給當前元素的某個事件綁定方法(不論是基於DOM0仍是DOM2),都是爲了觸發元素的相關行爲的時候,能把綁定的方法執行,不只把方法執行,並且瀏覽器還給方法傳遞了一個實參信息 ===>事件對象數組
MouseEvent
鼠標事件對象KeyboardEvent
鍵盤事件對象Event
普通事件對象TouchEvent
手指事件對象MouseEvent
:鼠標事件對象中的屬性】ev.target
: 事件源(操做的是哪一個元素),在嵌套關係中,給上層元素綁定事件,能夠經過事件源,查到事件觸發的對象(元素)ev.target.tagName
: 'LI' 查看標籤名(大寫)ev.clientX
/ ev.clientY
: 當前鼠標觸發點距離當前窗口可視區左上角的X/Y軸座標ev.pageX
/ ev.pageY
: 當前鼠標觸發點距離body(第一屏幕)左上角X/Y軸座標
pageXOffset + event.clientX
(元素到body左邊的距離+元素自己寬度)pageYOffset + event.clientY
(元素到body頂部的距離+元素自己高度)ev.preventDefault()
: 阻止默認行爲ev.stopPropagation()
: 阻止事件的冒泡傳播(低版本瀏覽器不兼容)ev.cnacelBubble = true
: 阻止事件的冒泡傳播(chrome/IE: window中都有一個event對象,火狐中沒有event對象)ev.type
: 當前事件類型KeyboardEvent
: 鍵盤事件對象中的屬性】ev.keycode
: 當前按鍵的鍵盤碼(數字類型) 13v.ctrlKey
: 布爾值ev.shiftKey
: 布爾值ev.altKey
: 布爾值 [經常使用的鍵盤碼]// MouseEvent 鼠標事件對象
box.onclick = function(ev){
//定義一個形參ev用來接收方法執行的時候,瀏覽器傳遞的信息值(事件對象)
console.log(ev);
//MouseEvent {isTrusted: true, screenX: 52, screenY: 161, clientX: 52, clientY: 58, …}
}
複製代碼
// KeyboardEvent 鍵盤事件對象
box.onkeydown = function(ev){
console.log(ev);
}
input.onkeydown = function(ev){
console.log(ev); //KeyboardEvent {isTrusted: true, key: "Enter", code: "Enter", location: 0, ctrlKey: false, …}
}
複製代碼
// Event 普通事件對象
window.onload = function(ev){
console.log(ev); //Event {isTrusted: true, type: "load", target: document, currentTarget: Window, eventPhase: 2, …}
}
複製代碼
結構和樣式瀏覽器
<input type="text" id="txt">
<ul id="ul"></ul>
複製代碼
let ul = document.getElementById('ul')
txt.addEventListener('keyup',function(ev){
console.log(ev);
// 同時按住ctrl鍵和enter鍵 就把input輸入框中輸入的內容插入到已有li元素的前面
if(ev.keyCode === 13 && ev.ctrlKey){
ul.insertAdjacentHTML('afterbegin',`<li>${this.value}</li>`)
}
})
複製代碼
mouseover
: 鼠標通過mouseout
:鼠標移出mouseenter
:鼠標進入(阻止冒泡傳播)mouseleave
:鼠標離開(阻止冒泡傳播) 真實項目中多用 mouseenter
/mouseleave
結構和樣式bash
<style>
#outer {
position: absolute;
top: 30px;
left: 30px;
width: 500px;
height: 500px;
background: red;
cursor: pointer;
}
#inner {
position: absolute;
top: 30px;
left: 30px;
width: 150px;
height: 150px;
background: #fff;
cursor: pointer;
}
</style>
複製代碼
<div id="outer">
<div id="inner"></div>
</div>
複製代碼
// 用onmouseover / onmouseout
inner.onmouseover = function () {
console.log('進入白盒子')
}
inner.onmouseout = function () {
console.log('離開白盒子')
}
outer.onmouseover = function () {
console.log('進入紅盒子')
}
outer.onmouseout = function () {
console.log('離開紅盒子')
}
複製代碼
// 用onmouseenter / onmouseleave
inner.onmouseenter = function () {
console.log('進入白盒子')
}
inner.onmouseleave = function () {
console.log('離開白盒子')
}
outer.onmouseenter = function () {
console.log('進入紅盒子')
}
outer.onmouseleave = function () {
console.log('離開紅盒子')
}
複製代碼
事件自己就是天生就有的,某些事件觸發,即便沒有綁定方法,也會存在一些效果,這些默認的效果就是事件的默認行爲服務器
<a href="http://www.baidu.com" target="_blank"><a/>
<a href="#box" target="_blank"><a/>
hash
值,瀏覽器檢測到hash值後,會默認定位到當前頁面中id和hash相同的盒子的位置(基於hash值實現spa單頁面應用)在form
當中設置anction
,點擊submit
,會默認按照anction
的地址進行頁面跳轉,而且把表單中的信息傳遞進去(非先後端分離項目中,有服務器進行頁面渲染,由其餘語言實現數據交互)前後端分離
<form action="https://www.baidu.com/">
<input type="submit" value="提交"/>
</form>
複製代碼
不少時候咱們使用a標籤僅僅是想作一個普通的按鈕,點擊實現一個功能,不想頁面跳轉,也不想錨點定位ide
<a href="javascript:void 0/undefined/null/false;">珠峯最新視頻</a>
給其click事件綁定方法,當咱們點擊a標籤,先觸發click事件,其次纔會執行本身的默認行爲
ev.returnValue = false;
(支持DOM0和DOM2,能夠設置布爾值來控制是否阻止默認行爲)return false;
(只支持DOM0)ev.preventDefault();
(DOM2經常使用)若是想阻止某部分元素的默認行爲,在指定元素下阻止便可;若是在document上阻止默認行爲,那麼整個文檔中的默認行爲都會被阻止
// 阻止a標籤的默認行爲
link.onclick = function(ev){
ev = ev || window.event;
// return false;
ev.preventDefault ? ev.preventDefault():ev.returnValue = false;
}
複製代碼
// 阻止input標籤的默認行爲,即不能輸入內容
// DOM0
input1.onkeydown = function(ev){
// ev = ev || window.event;
ev.preventDefault() ? ev.preventDefault() : ev.returnValue = false;
// return false;
}
// DOM2
input1.addEventListener('keydown',function(ev){
ev.preventDefault();
})
複製代碼
// 阻止右鍵菜單的默認行爲
document.addEventListener('contextmenu',function(ev){
ev.preventDefault()
})
複製代碼
觸發當前元素的某一個事件(好比點擊事件)行爲,不只當前元素事件行爲觸發,並且其祖先元素的相關事件行爲也會被依次觸發,這種機制就是事件的傳播機制
window
對象傳導到目標節點(上層傳到底層),稱爲「捕獲階段」(capture phase)。window
對象(從底層傳回上層),稱爲「冒泡階段」(bubbling phase)。這三個階段的傳播模型,使得同一個事件會在多個節點上觸發
xxx.onxxx = function(){};
DOM0
級事件綁定方式,只有冒泡階段。若是事件綁定的是目標元素,就按照目標事件的前後順序依次綁定xxx.addEventListener('xxx',function(){},false);
第三個參數:
window.event
中),存儲的值是一個對象(堆內存);操做會觸發元素的某個行爲,把綁定的方法執行,此時標準瀏覽器會把以前存儲的對象(內存地址)當作實參傳遞給每個執行的方法,因此操做一次,即便再多方法中都有ev
,可是存儲的值都是一個(本次操做的信息對象)公共樣式:
<style>
#outer {
position: absolute;
top: 30px;
left: 30px;
width: 500px;
height: 500px;
background: red;
cursor: pointer;
}
#center {
position: absolute;
top: 30px;
left: 30px;
width: 300px;
height: 300px;
background: pink;
cursor: pointer;
}
#inner {
position: absolute;
top: 30px;
left: 30px;
width: 150px;
height: 150px;
background: #fff;
cursor: pointer;
}
</style>
複製代碼
<div id="outer">
<div id="center">
<div id="inner">
<button id="btn">按鈕</button>
</div>
</div>
</div>
複製代碼
let aa = null;
window.onclick = function(ev){
console.log(ev === aa); //true
alert('window')
}
outer.onclick = function(ev){
console.log(ev === aa); //true
alert('紅盒子')
}
center.onclick = function(ev){
console.log(ev === aa); //true
alert('粉盒子')
}
inner.onclick = function(ev){
aa = ev;
alert('白盒子')
}
btn.onclick = function(ev){
ev = ev || window.event;
ev.stopPropagation()?ev.stopPropagation():ev.cancelBubble = true;
// 阻止冒泡傳播 ev.stopPropagation()低版本不兼容 ev.cancelBubble = true 全部瀏覽器都兼容
alert('按鈕')
}
複製代碼
//結構和樣式同上
function fn() { alert('btn1'); }
btn.addEventListener('click', fn, true);
outer.addEventListener('click',function(){alert('red');});
btn.addEventListener('click', fn, true);
inner.addEventListener('click', function () { alert('yellow'); }, true);
center.addEventListener('click', function () { alert('green'); });
btn.addEventListener('click', function () { alert('btn捕獲'); }, true);
btn.addEventListener('click', function () { alert('btn冒泡'); });
btn.addEventListener('click', fn, false);
// 答案:yellow btn1 btn捕獲 btn冒泡 btn1 green red
複製代碼
利用事件冒泡傳播機制,若是一個容器的後代元素當中,不少元素的點擊行爲(其餘事件行爲也是)都要作一些處理,此時咱們不須要再像之前同樣一個個獲取一個個綁定,只須要給容器的click綁定方法便可,這樣無論點擊的是哪個後代元素,都會根據冒泡傳播機制把容器的click行爲觸發,把綁定的方法執行,根據事件源咱們能夠知道點擊的是誰,從而作不一樣的事情便可
ev.target
: 事件源(操做的是哪一個元素),在嵌套關係中,給上層元素綁定事件,能夠經過事件源,查到事件觸發的對象(元素)
tagName: 'LI'
查看標籤名(大寫)事件委託這種處理方式比一個個的事件綁定,性能上提升50%左右,並且須要操做的元素越多,性能提升越大
公共樣式:
<style>
ul {
margin: 0 auto;
width: 100px;
border: 2px solid fuchsia;
}
li {
width: 50px;
height: 50px;
border: 1px solid #000;
}
</style>
複製代碼
<ul id="ul">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
複製代碼
// 給全部li的上級元素ul綁定點擊事件,則其全部後代元素都會執行這個方法
ul.addEventListener('click',function(ev){
ev.target.style.background = 'green'
})
複製代碼
// 點擊一個變色,點擊下一個變色,同時上一個取消變色
let lis = document.querySelectorAll('#ul>li')
ul.onclick = function (ev) {
// console.log(ev.target.tagName); // 'LI'
// ev.target.tagName 即當前點擊的標籤的標籤名(大寫)
if (ev.target.tagName === 'LI') {
for (let i = 0; i < lis.length; i++) {
// 循環全部的li元素,若是當前循環的li元素不等於當前點擊的li元素,就把當前循環的li元素的背景顏色清空,若是當前循環的li元素等於當前點擊的元素,就把當前點擊的li元素加上顏色
if (lis[i] !== ev.target) {
lis[i].style.background = '';
} else {
ev.target.style.background = 'green';
}
}
}
}
複製代碼
DOM0: element.onxxx = function(){}
每個元素對象都是對應類的實例,瀏覽器天生爲其設置了不少私有屬性和公有的屬性方法,而onclick
就是其中的一個私有屬性(事件相似私有屬性,還有不少其餘的事件私有屬性),這些屬性默認值是null
element.addEventListener('xxx', function(){}, false);
ele.removeEventListener('click', listener, false);
EventTarget.prototype
上定義的DOMContentLoaded
事件(當頁面中的頁面中HTML結構加載完成就會觸發執行)// DOM0事件綁定:只容許給當前元素的某個事件行爲綁定一個方法,屢次綁定,後面綁定的內容會替換前面綁定的,以最後一次綁定的方法爲主
box.onclick = function(){
console.log(1)
}
box.onclick = function(){
console.log(2);// 觸發點擊行爲,只輸出2
}
複製代碼
// DOM2事件綁定
function fn1(){console.log(1)}
function fn2(){console.log(2)}
function fn3(){console.log(3)}
function fn4(ev){
console.log(4,this === box,ev.target)
box.removeEventListener('click',fn5);
box.removeEventListener('click',fn8);
}
function fn5(){console.log(5)}
function fn6(){console.log(6)}
function fn7(){console.log(7)}
function fn8(){console.log(8)}
function fn9(){console.log(9)}
function fn10(){console.log(10)}
box.addEventListener('click',fn1);
box.addEventListener('click',fn3);
box.addEventListener('click',fn5);
box.addEventListener('click',fn7);
box.addEventListener('click',fn9);
box.addEventListener('click',fn2);
box.addEventListener('click',fn2);//重複
box.addEventListener('click',fn2);//重複
box.addEventListener('mouseenter',fn2); //增長到事件池當中的
box.addEventListener('click',fn4);
box.addEventListener('click',fn6);
box.addEventListener('click',fn8);
box.addEventListener('click',fn10);
複製代碼
在上個例子中:
首先在事件未執行前,會把box的click的全部方法添加到一個數組裏面(即添加到事件池裏面),此時數組中有[fn1,fn3,fn5,fn7,fn9,fn2,fn4,fn6,fn8,fn10]
當第一次點擊box,會依次輸出1,3,5,7,9,2,4(此時移除了數組中的fn5和fn8方法),6,10
當第二次點擊box,會依次輸出1,3,7,9,2,4,6,10
let fn = function(){ }
box.addEventListener('DOMContentLoaded',fn); //能夠
box.onDOMContentLoaded = fn; //不能夠,box沒有這個屬性
複製代碼
結構和樣式
<style>
#box {
width: 100px;
height: 100px;
position: absolute;
top: 0;
left: 0;
background: red;
}
body{
height: 3000px;
}
</style>
複製代碼
<div id="box"></div>
複製代碼
js代碼
document.onmousemove = function (ev) {
// console.log(ev.clientX);
// console.log(ev.clientY);
// 實現鼠標在盒子中間:ev.pageX: 鼠標離窗口左邊的距離 - 盒子寬度的一半 此時left:盒子左邊到瀏覽器左邊的距離
let left = ev.pageX - box.clientWidth / 2;
let top = ev.pageY - box.clientHeight / 2;
if (left < 0) {
left = 0;
}
if (left > document.documentElement.clientWidth - box.clientWidth) {
// document.documentElement.clientWidth - box.clientWidth 即盒子距離窗口左邊的最大距離(超過此最大距離,盒子就會溢出窗口)
// 盒子到瀏覽器左邊的距離 > 最大距離,就讓盒子到瀏覽器左邊的距離 = 最大距離
left = document.documentElement.clientWidth - box.clientWidth;
}
if (top < 0) {
top = 0;
} else if (top > document.documentElement.clientHeight - box.clientHeight) {
top = document.documentElement.clientHeight - box.clientHeight;
}
//讓盒子距窗口左邊/頂部的距離 = 鼠標離窗口左邊/頂部的距離
box.style.left = left + 'px';
box.style.top = top + 'px';
}
複製代碼
結構和樣式
<style>
#box {
width: 100px;
height: 100px;
position: absolute;
top: 0;
left: 0;
background: red;
}
</style>
複製代碼
<div id="box"></div>
複製代碼
js代碼
num1 = 0;
num2 = 0
let timer = null;
document.addEventListener('keydown', function move(ev) {
clearInterval(timer);
timer = setInterval(() => {
switch (ev.keyCode) {
case 39:
num1 += 10;
// box.style.left = num1 + 'px';
break;
case 40:
num2 += 10;
// box.style.top = num2 + 'px';
break;
case 37:
num1 -= 10;
// box.style.left = num1 + 'px';
break;
case 38:
num2 -= 10;
// box.style.top = num2 + 'px';
break;
}
num1 < 0 ? num1 = 0 : null;
box.style.left = num1 + 'px';
num2 < 0 ? num2 = 0 : null;
box.style.top = num2 + 'px';
}, 22)
});
document.addEventListener('keyup',function(){
clearInterval(timer)
})
複製代碼