最近又在重新复习js,不怎么用有些就就生疏了,每天都要复习复习在复习才行,分享一下跟着腾讯视频的日常笔记记录。
有些錯誤可能是沒寫對中英字符,可能會報錯,都手寫的,見諒,废话不多说半句,开始复习吧!
* 事件的概念
javascript使我們有能力創建動態頁面,網頁中的每個元素都可以產生某些可以觸發javascript函數的事件。我們可以認為事件是可以被javascript偵測到的一種行為
* 事件流
事件主要分為冒泡型事件和捕獲型事件。IE瀏覽器目前只支持冒泡型事件,而支持標準的DOM的瀏覽器比如火狐和谷歌等兩者都支持。
· 事件冒泡
ie 的事件流叫事件冒泡,也就是說事件的傳播為:從事件開始的具體元素,一級級往上傳播到較為不具體的節點。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>事件冒泡</title> </head> <body> <div> <p>點我</p> </div> </body> </html>
原文網址:https://kknews.cc/news/86jm3n.html
當我們點擊P元素時,事件是這樣傳播的:
(1) p
(2) div
(3) body
(4) html
(5) document
現代瀏覽器都支持事件冒泡,IE9、Firefox、Chrome和Safari則將事件一直冒泡到window對象。
但是如果我們不希望事件冒泡呢?那麼如何阻止事件冒泡?
實際上,事件的對象有一個stopPropagation方法可以阻止事件冒泡,我們只需要把上個例子中button的事件處理程序修改如下:
document.getElementById("button").addEventListener("click",function(event){ alert("button");
event.stopPropagation;
},false);
這樣,點擊button後,只會彈出一個彈窗,顯示button。
注意:現代所有的瀏覽器都支持事件冒泡,只是在實現上有一些差別。
· 事件捕獲
Netscape團隊提出的另一種事件流叫做事件捕獲。它的原理剛好和事件冒泡相反,它的用意在於在事件到達預定目標之前捕獲它,而最具體的節點應該是最後才接收到事件的。
比如還是上面的案例,當點擊P元素時,事件的傳播方向就變成了這樣:
(1) document
(2) html
(3) body
(4) div
(5) p
IE9、Firefox、Chrome和Safari目前也支持這種事件流模型,但是有些老版本的瀏覽器不支持,所以很少人使用事件捕獲,而是用事件冒泡的多一點。
我們可以使用DOM3級新增事件stopImmediatePropagation方法來阻止事件捕獲,另外此方法還可以阻止事件冒泡。應用如下:
document.getElementById("second").addEventListener("click",function{
alert("second");
event.stopImmediatePropagation;
},true);
這樣,就可以在id為second處阻止事件的捕獲了。
注意:儘管這是Netscape Navigator提出的事件流,但是現在所有的瀏覽器都支持這種事件流模型。但是由於老的瀏覽器不支持,所以很少有人使用事件捕獲。
原文網址:https://kknews.cc/game/xzpon68.html
* DOM事件流
"DOM2級事件"規定的事件流包括三個階段:
- 事件捕獲階段
- 處於目標階段
- 事件冒泡階段
在DOM事件流中,事件的目標在捕獲階段不會接受到事件。這意味著在捕獲階段,事件從document到p後就定停止了。
下一個階段是處於目標階段,於是事件在p上發生,並在事件處理中被看成冒泡階段的一部分。然後,冒泡階段發生,事件又傳播回document。
* 事件處理程序
btn.addEventListener(eventType, function { }, false); 該方法應用至dom節點 第一個參數為事件名 第二個為事件處理程序 第三個為布爾值,true為事件捕獲階段調用事件處理程序,false為事件冒泡階段調用事件處理程序
使用例子如下:
var btn = document.getElementById('btn');
btn.addEventListener('click', function { alert('事件捕獲'); }, true); btn.addEventListener('click', function { alert('事件冒泡'); }, false);
依次彈出「事件捕獲」和「事件冒泡」,在這裡的第一反應就是,他們有先後順序嗎?
於是我反過來寫:
var btn = document.getElementById('btn');
btn.addEventListener('click', function { alert('事件冒泡'); }, false); btn.addEventListener('click', function { alert('事件捕獲'); }, true);
依次彈出的是:「事件冒泡」和「事件捕獲」;到底有沒有先後順序呢?繼續往下走
這次是這樣的寫法:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件冒泡</title>
</head>
<body>
<div>
<p id="parEle">我是父元素
<span id="sonEle">我是子元素</span>
</p>
</div>
</body>
</html>
<script type="text/javascript">
var sonEle = document.getElementById('sonEle');
var parEle = document.getElementById('parEle');
parEle.addEventListener('click', function { alert('父級 冒泡'); }, false); parEle.addEventListener('click', function { alert('父級 捕獲'); }, true); sonEle.addEventListener('click', function { alert('子級冒泡'); }, false); sonEle.addEventListener('click', function { alert('子級捕獲'); }, true); </script>
當點擊「我是子元素」 時,彈出的順序是:「父級捕獲」--》「子級冒泡」--》「子集捕獲」--》「父集冒泡」;
這裡可以說明,當點擊子元素時,父級的執行順序是先捕獲,後冒泡的。
綜合前面的代碼,我們可以得出一個小小的結論:
當容器元素及嵌套元素,即在捕獲階段又在冒泡階段調用事件處理程序時:事件按DOM事件流的順序執行事件處理程序
且當事件處於目標階段時,事件調用順序決定於綁定事件的書寫順序,按上面的例子為,先調用冒泡階段的事件處理程序,再調用捕獲階段的事件處理程序。依次alert出「子集冒泡」,「子集捕獲」。
原文網址:https://kknews.cc/news/86jm3n.html
* 使用返回值改變HTML元素的默認行為
HTML元素大都包含了自己的默認行為,如:超鏈接,提交按鈕等。我們可以通過在綁定事件中加上return false
來阻止他的默認行為。
* 通用性的事件監聽方法
綁定HTML元素屬性
<input type="button" value ="myclick" onclick="check(this)">
綁定DOM對象屬性
document.getElementById("btn").onclick=test;
* IE中事件監聽方法
· [object].attachEvent("事件類型","處理函數");//添加監聽
· [object].detachEvent("事件類型","處理函數");//取消監聽
* 標準DOM中的事件監聽方法
· [object].addEventListener("事件類型","處理函數","冒泡事件或捕獲事件")
· [object].removeEventListener("事件類型","處理函數","冒泡事件或捕獲事件")
提示:IE監聽方法中的事件類型和標準DOM監聽方法中的事件類型寫法有點相同,前者事件類型“on”開頭,如“onclick”,“onmousemove”等,而後者不需要去掉“on”,就是“click”,“mousemove”等
栗子一:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
<button type="button" id="text1">firefox1</button>
<button type="button" id="text2">firefox2</button>
<script>
function text(){
alert("我能顯示了");
}
var textid1 = document.getElementById("text1");
var textid2 = document.getElementById("text2");
textid1.addEventListener("click",text);
textid2.onclick=function(){
textid1.removeEventListener("click",text,false)
}
</script>
</body>
</html>
結果為:點擊Firefox1就彈出我能顯示了的文字。再點擊firefox2的話就移除了Firefox1的click事件了
栗子二:
var btn=document.getElementById('myBtn');
var myFn=function{ alert(this.id); }
btn.addEventListener('click',myFn,false);
btn.removeEventListener('click',myFn,false);
注意點:為了最大限度的兼容,大多是情況下都是將事件處理程序添加到事件冒泡階段。不是特別需要,不建議在事件捕獲階段註冊事件處理程序
原文網址:https://kknews.cc/news/86jm3n.html
* 兼容ie瀏覽器寫法:
var EventUtil =
{
addHandler: function (el, type, handler)
{
if (el.addEventListener)
{
el.addEventListener(type, handler, false);
}
else {
el.attachEvent('on' + type, handler);
}
},
removeHandler: function (el, type, handler) {
if (el.removeEventListener) {
el.removeEventListerner(type, handler, false);
} else {
el.detachEvent('on' + type, handler);
}
}
};
用法和前面的類似:
EventUtil.addHandler('btn','click',handler);
* 事件對象
觸發dom上的某個事件時,會產生一個事件對象,裡面包含著所有和事件有關的信息。
比較常用的有以下幾個:
currentTarget 事件處理程序當前正在處理事件的那個元素(始終等於this)
preventDefault 取消事件默認行為,比如連結的跳轉
stopPropagation 取消事件冒泡
target 事件的目標
兼容ie的事件對象:
var EventUtil = {
addHandler: function (el, type, handler) {
if (el.addEventListener) {
el.addEventListener(type, handler, false);
}
else if (el.attachEvent) {
el.attachEvent('on' + type, handler);
} else {
el['on' + type] = handler;
}
},
removeHandler: function (el, type, handler) {
if (el.removeEventListener) {
el.removeEventListerner(type, handler, false);
}
else if (el.detachEvent) {
el.detachEvent('on' + type, handler);
} else {
el['on' + type] = null;
}
},
getEvent: function (e) {
return e ? e : window.event;
},
getTarget: function (e) {
return e.target ? e.target : e.srcElement;
},
preventDefault: function (e) {
if (e.preventDefault) { e.preventDefault;
}
else {
e.returnValue = false;
}
},
stopPropagation: function (e) {
if (e.stopPropagation) {
e.stopPropagation;
} else {
e.cancelBubble = true;
}
}
};
其他
html5事件之 beforeunload
在頁面卸載前觸發,就像編輯博客園文章未保存是彈出的提示框一樣。
html5事件之 DOMContentLoaded事件
支持頁面下載前添加事件,而不需要等待圖片,css文件,或者其他文件加載完畢才執行。可以讓用戶能夠儘早的與用戶進行交互。
EventUtil.addHandler(document,'DOMContentLoaded',function{ alert('我可以先執行,哈哈') })
事件委託:
每個函數都是對象,都會占用內存,內存中的對象越多,性能就越差。對事件處理程序過多問題的解決方案就是事件委託。
事件委託利用事件冒泡,只指定一個事件處理程序即可,就可以管理某一個類型的所有事件。例如:
有三個li,都需要一個click事件,此時不需要給每個li都綁定click事件,主要給他的父級 ul增加一個綁定事件即可。這樣點擊li,利用冒泡,直接觸發ul的click,只要判斷是哪個li的id
點擊即可。而不需要三個li都綁定click事件。
<ul id="myLinks">
<li id="myLi1">text1</li>
<li id="myLi2">text2</li>
<li id="myLi3">text3</li>
</ul>
原文網址:https://kknews.cc/news/86jm3n.html