
JS事件事件最重要的概念就是事件源事件名監(jiān)聽器處理程序01 事件流就是事件傳播描述的是從頁面中接收事件的順序如果單擊了某個按鈕它們認為單擊事件不僅僅發(fā)生在按鈕上甚至單擊了整個頁面IE事件流是事件冒泡流Netscape是事件捕獲流其實不同的就是事件的觸發(fā)時機是在捕獲階段觸發(fā)事件還是在冒泡階段觸發(fā)事件02 事件冒泡和事件捕獲的概念事件冒泡事件由當前最具體的元素接收然后逐級向上傳播到較為不具體的節(jié)點文檔documentdiv idbox/div // 點擊box點擊事件會向上傳播box的每一層父級都會觸發(fā)它們身上的點擊事件 script const box document.getElementById(box); box.onclick function () { box.innerHTML divbr; } // 獲取body document.body.onclick function () { box.innerHTML bodybr; } // 獲取html document.documentElement.onclick function () { box.innerHTML htmlbr; } // 獲取document document.onclick function () { box.innerHTML documentbr; } // 獲取window window.onclick function () { box.innerHTML windowbr; } /script事件捕獲事件由不太具體的節(jié)點更早的接收事件而最具體的節(jié)點應該最后接收到事件逐級向下傳播div idbox/div script const box document.getElementById(box) box.addEventListener(click, function () { box.innerHTML boxbr },true) // addEventListener的第三個參數用來控制事件觸發(fā)時機在捕獲階段true還是在冒泡階段false這個參數還可以時一個對象 /* { capture: true, // 是否捕獲階段執(zhí)行 once: true, // 是否只執(zhí)行一次 passive: true // 是否阻止preventDefault } */ document.body.addEventListener(click, function () { box.innerHTML bodybr },true) ? document.documentElement.addEventListener(click, function () { box.innerHTML htmlbr },true) ? document.addEventListener(click, function () { box.innerHTML documentbr },true) ? window.addEventListener(click, function () { box.innerHTML windowbr },true) /script03 三種事件處理程序的綁定方式關于三種方式的this指向問題body button classbtnClick Me/button script const btn document.querySelector(.btn) // btn.onclick function () { // console.log(this) // 當前dom對象 // } ? // btn.onclick () { // console.log(this) // window // } ? // btn.addEventListener(click,function() { // console.log(this) // 當前dom對象 // }) ? btn.addEventListener(click,() { console.log(this) // window }) /script /body1、HTML事件處理程序!DOCTYPE html html langen head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 titleDocument/title style #app{ width: 200px; height: 100px; background-color: pink; } /style /head body div idapp onclickconsole.log(event)/div div idapp2 onclicktest(event)/div script function test(e){ console.log(e) } /script /body /html// 只要是html事件處理程序瀏覽器都會對簡單代碼語句進行包裝因為這里面實際上都是字符串是不能執(zhí)行的函數調用語句也是的實際上也只是一個函數調用語句的字符串 // 下面是對兩種形式的包裝方式 element.onclick function(event) { test(event); // 把你寫在 onclick 里的字符串代碼直接塞到這里執(zhí)行 }; element.onclick function(event) { console.log(event); }; // 所以這種方式也可以看作是通過外層包裝函數的第一個參數接收事件對象2、DOM0級事件處理程序!DOCTYPE html html langen head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 titleDocument/title style #app { width: 200px; height: 100px; background-color: pink; } /style /head body div idapp /div ? script const box document.getElementById(app) box.onclick function(e){ // 這種方式相當于是給執(zhí)行的dom對象屬性綁定方法所以這里的this指向當前dom對象 console.log(this) // 這里的全局事件對象event就是瀏覽器已經維護好的可以直接使用在window對象上 console.log(event) // 當然這里也是可以通過事件處理程序的第一個參數來接收事件對象 console.log(e) } /script /body /html3、DOM2級事件處理程序!DOCTYPE html html langen head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 titleDocument/title style #app{ width: 200px; height: 100px; background-color: pink; } /style /head body div idapp/div script const box document.getElementById(app) box.addEventListener(click,function(e){ console.log(this) // 這里明顯沒有傳遞參數所以這里的event還是window上的全局事件對象 console.log(event) // 當然這里也是可以通過事件處理程序的第一個形參來接收事件對象 console.log(e) }) /script /body /html04 事件綁定的兼容寫法!DOCTYPE html html langen head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 titleDocument/title /head body button idbtn你過來呀/button script // DOM2級事件處理程序addEventListener,ie不支持需要使用attachEvent const btn document.getElementById(btn) // btn.addEventListener(click,fn) // btn.attachEvent(onclick,fn) addEvent(btn,click,function(){ console.log(this) }) // 定義兼容性綁定函數,attachEvent中的this指向window,也需要做兼容處理 function addEvent(element,type,handler){ if(element.addEventListener){ element.addEventListener(type,handler,false) }else if(element.attachEvent){ element.attachEvent(on type,function(){ handler.call(element) }) } } /script ? /body /html05事件調用順序!DOCTYPE html html langen head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 titleDocument/title style #box{ width: 200px; height: 200px; background-color: pink; } /style /head body div idbox onclickthis.innerHTML html\n/div script // 如果同時出現html級事件處理程序和DOM0級事件處理程序html級會被覆蓋掉 const box document.getElementById(box) box.onclick function(){ this.innerHTML DOM0\n } ? box.addEventListener(click,function(){ this.innerHTML DOM2\n }) /script ? /body /html06事件目標對象!DOCTYPE html html langen head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 titleDocument/title style typetext/css .item { width: 100px; height: 80px; background-color: lightblue; margin: 50px 10px; } /style /head body ul idbox li classitem1/li li classitem2/li /ul script const box document.getElementById(box) box.onclick function(e){ e e || window.event // 1、currentTarget 事件綁定的元素 console.log(e.currentTarget) // 2、target 事件觸發(fā)的元素 console.log(e.target) // 3、srcElement 事件觸發(fā)的元素兼容性好 console.log(e.srcElement) ? // this 指向事件綁定的元素 console.log(e.currentTarget this) console.log(e.target this) ? // 兼容性處理 let target e.target || e.srcElement } /script ? /body /html07 事件代理事件委托!DOCTYPE html html langen head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title事件代理/title style * { margin: 0; padding: 0; } ul { list-style: none; overflow: hidden; margin-top: 50px; } ul li { float: left; width: 100px; height: 30px; background-color: lightblue; text-align: center; line-height: 30px; margin: 0 10px; color: #fff; } /style /head body ul li1/li li2/li li3/li li4/li li5/li /ul script window.onload function () { const ul document.querySelector(ul) setTimeout(() { const item document.createElement(li) item.innerHTML 6 ul.appendChild(item) }, 100) ? // 獲取所有l(wèi)i元素這里只獲取了原來的5個li元素新增的li元素沒有添加事件監(jiān)聽所以不會觸發(fā)事件 // const lis document.querySelectorAll(li) // lis.forEach(item { // item.addEventListener(mouseover,function () { // this.style.backgroundColor red // }) // item.addEventListener(mouseout,function () { // this.style.backgroundColor lightblue // }) // }) ? // 給未來的li添加事件監(jiān)聽這里使用事件代理 ul.addEventListener(mouseover,function (e) { if(e.target.tagName LI){ e.target.style.backgroundColor red } }) ul.addEventListener(mouseout,function (e) { if(e.target.tagName LI){ e.target.style.backgroundColor lightblue } }) } /script /body /html08 事件冒泡阻止冒泡!DOCTYPE html html langen head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title事件冒泡/title ? /head body button idbtn stylewidth: 200px; height: 30px;點擊我/button input typetext idtest script // 兩個屬性兩個方法 bubbles cancelBubble stopPropagation() stopImmediatePropagation() // 1、bubble 返回一個布爾值表示當前事件是否冒泡注意大部分事件都是冒泡事件但是focus blur scroll事件不是冒泡事件 const btn document.getElementById(btn) const test document.getElementById(test) ? btn.addEventListener(click,function(e){ console.log(e.bubbles) // true }) test.addEventListener(focus,function(e){ console.log(e.bubbles) // false }) // 2、cancelBubble 取消事件冒泡,也不能阻止同一事件的其他監(jiān)聽函數執(zhí)行 btn.addEventListener(click,function(e){ e.cancelBubble true }) // 3、stopPropagation() 取消事件冒泡ie8不支持但是它無法阻止同一事件的其他監(jiān)聽函數執(zhí)行 // 4、stopImmediatePropagation() 取消事件冒泡ie8不支持但是它可以阻止同一事件的其他監(jiān)聽函數執(zhí)行 btn.addEventListener(click,function(e){ e e || window.event // e.stopImmediatePropagation() this.innerHTML 阻止冒泡 }) btn.addEventListener(click,function(e){ console.log(按鈕的另一個監(jiān)聽函數執(zhí)行了) }) document.body.onclick function(){ console.log(這里打印就是冒泡了沒打印就是沒有冒泡) } /script /body /html09 取消默認事件!DOCTYPE html html langen head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title取消默認事件/title /head body !-- 這兩種方式都是讓瀏覽器執(zhí)行一段“返回空值”的代碼騙過瀏覽器讓其不跳轉 -- a hrefjavascript:;返回空值取消默認事件/a a hrefjavascript:void(0);void(0)取消默認事件/a a hrefhttp://www.baidu.com idbaidu事件對象取消默認事件/a ? script // 事件對象的兩個方法來阻止默認行為 var a document.getElementById(baidu); a.onclick function(e) { e e || window.event; // 阻止默認行為 ie8不支持 // e.preventDefault(); // 阻止默認事件兼容ie8以下的瀏覽器 // e.returnValue false; // 兼容寫法 if(e.preventDefault) { e.preventDefault(); } else { e.returnValue false; } // 這樣也可以阻止默認行為,兼容了所有瀏覽器 return false } /script /body /html10事件對象中的坐標位置!DOCTYPE html html langen head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title鼠標事件對象屬性/title style #box{ width: 200px; height: 200px; background-color: red; } /style /head body div idparent div idbox/div /div script var box document.getElementById(box); box.onclick function(event){ // 相對于瀏覽器有效窗口的坐標也就是相對于body的坐標 console.log(event.clientX); console.log(event.clientY); // 相對于我電腦顯示器的坐標 console.log(event.screenX); console.log(event.screenY); // 相對于瀏覽器頁面的距離包括滾動條 console.log(event.pageX); console.log(event.pageY); // 相對于當前事件源的偏移坐標 console.log(event.offsetX); console.log(event.offsetY); } ? /script /body /html