. this 適合你嗎?
我看到許多文章在介紹 JavaScript 的 this 時都會假設(shè)你學(xué)過某種面向?qū)ο蟮木幊陶Z言,比如 Java、C++ 或 Python 等。但這篇文章面向的讀者是那些不知道 this 是什么的人。我盡量不用任何術(shù)語來解釋 this 是什么,以及 this 的用法。
也許你一直不敢解開 this 的秘密,因為它看起來挺奇怪也挺嚇人的。或許你只在 StackOverflow 說你需要用它的時候(比如在 React 里實現(xiàn)某個功能)才會使用。
在深入介紹 this 之前,我們首先需要理解函數(shù)式編程和面向?qū)ο缶幊讨g的區(qū)別。
2. 函數(shù)式編程 vs 面向?qū)ο缶幊?/strong>
你可能不知道,JavaScript 同時擁有面向?qū)ο蠛秃瘮?shù)式的結(jié)構(gòu),所以你可以自己選擇用哪種風(fēng)格,或者兩者都用。
我在很早以前使用 JavaScript 時就喜歡函數(shù)式編程,而且會像躲避瘟疫一樣避開面向?qū)ο缶幊蹋驗槲也焕斫饷嫦驅(qū)ο笾械年P(guān)鍵字,比如 this。我不知道為什么要用 this。似乎沒有它我也可以做好所有的工作。
而且我是對的。
在某種意義上 。也許你可以只專注于一種結(jié)構(gòu)并且完全忽略另一種,但這樣你只能是一個 JavaScript 開發(fā)者。為了解釋函數(shù)式和面向?qū)ο笾g的區(qū)別,下面我們通過一個數(shù)組來舉例說明,數(shù)組的內(nèi)容是 Facebook 的好友列表。
假設(shè)你要做一個 Web 應(yīng)用,當(dāng)用戶使用 Facebook 登錄你的 Web 應(yīng)用時,需要顯示他們的 Facebook 的好友信息。你需要訪問 Facebook 并獲得用戶的好友數(shù)據(jù)。這些數(shù)據(jù)可能是 firstName、lastName、username、numFriends、friendData、birthday 和 lastTenPosts 等信息。
const data=[ { firstName: 'Bob', lastName: 'Ross', username: 'bob.ross', numFriends: 125, birthday: '2/23/1985', lastTenPosts: ['What a nice day', 'I love Kanye West', ...], }, ... ]
假設(shè)上述數(shù)據(jù)是你通過 Facebook API 獲得的。現(xiàn)在需要將其轉(zhuǎn)換成方便你的項目使用的格式。我們假設(shè)你想顯示的好友信息如下:
3. 函數(shù)式方式
函數(shù)式的方式就是將整個數(shù)組或者數(shù)組中的某個元素傳遞給某個函數(shù),然后返回你需要的信息:
const fullNames=getFullNames(data) // ['Ross, Bob', 'Smith, Joanna', ...]
首先我們有 Facebook API 返回的原始數(shù)據(jù)。為了將其轉(zhuǎn)換成需要的格式,首先要將數(shù)據(jù)傳遞給一個函數(shù),函數(shù)的輸出是(或者包含)經(jīng)過修改的數(shù)據(jù),這些數(shù)據(jù)可以在應(yīng)用中向用戶展示。
我們可以用類似的方法獲得隨機三篇文章,并且計算距離好友生日的天數(shù)。
函數(shù)式的方式是:將原始數(shù)據(jù)傳遞給一個函數(shù)或者多個函數(shù),獲得對你的項目有用的數(shù)據(jù)格式。
4. 面向?qū)ο蟮姆绞?/strong>
對于編程初學(xué)者和 JavaScript 初學(xué)者,面向?qū)ο蟮母拍羁赡苡悬c難以理解。其思想是,我們要將每個好友變成一個對象,這個對象能夠生成你一切開發(fā)者需要的東西。
你可以創(chuàng)建一個對象,這個對象對應(yīng)于某個好友,它有 fullName 屬性,還有兩個函數(shù) getThreeRandomPosts 和 getDaysUntilBirthday。
function initializeFriend(data) { return { fullName: `${data.firstName} ${data.lastName}`, getThreeRandomPosts: function() { // get three random posts from data.lastTenPosts }, getDaysUntilBirthday: function() { // use data.birthday to get the num days until birthday } }; } const objectFriends=data.map(initializeFriend) objectFriends[0].getThreeRandomPosts() // Gets three of Bob Ross's posts
面向?qū)ο蟮姆绞骄褪菫閿?shù)據(jù)創(chuàng)建對象,每個對象都有自己的狀態(tài),并且包含必要的信息,能夠生成需要的數(shù)據(jù)。
5. 這跟 this 有什么關(guān)系?
你也許從來沒想過要寫上面的 initializeFriend 代碼,而且你也許認(rèn)為,這種代碼可能會很有用。但你也注意到,這并不是真正的面向?qū)ο蟆?/p>
其原因就是,上面例子中的 getThreeRandomPosts 或 getdaysUntilBirtyday 能夠正常工作的原因其實是閉包。因為使用了閉包,它們在 initializeFriend 返回之后依然能訪問 data。關(guān)于閉包的更多信息可以看看這篇文章:作用域和閉包(https://github.com/getify/You-Dont-Know-JS/blob/master/scope%20%26%20closures/ch5.md)。
還有一個方法該怎么處理?我們假設(shè)這個方法叫做 greeting。注意方法(與 JavaScript 的對象有關(guān)的方法)其實只是一個屬性,只不過屬性值是函數(shù)而已。我們想在 greeting 中實現(xiàn)以下功能:
function initializeFriend(data) { return { fullName: `${data.firstName} ${data.lastName}`, getThreeRandomPosts: function() { // get three random posts from data.lastTenPosts }, getDaysUntilBirthday: function() { // use data.birthday to get the num days until birthday }, greeting: function() { return `Hello, this is ${fullName}'s data!` } }; }
這樣能正常工作嗎?
不能!
我們新建的對象能夠訪問 initializeFriend 中的一切變量,但不能訪問這個對象本身的屬性或方法。當(dāng)然你會問,
難道不能在 greeting 中直接用 data.firstName 和 data.lastName 嗎?
當(dāng)然可以。但要是想在 greeting 中加入距離好友生日的天數(shù)怎么辦?我們最好還是有辦法在 greeting 中調(diào)用 getDaysUntilBirthday。
這時輪到 this 出場了!
6. 終于——this 是什么
this 在不同的環(huán)境中可以指代不同的東西。默認(rèn)的全局環(huán)境中 this 指代的是全局對象(在瀏覽器中 this 是 window 對象),這沒什么太大的用途。而在 this 的規(guī)則中具有實用性的是這一條:
如果在對象的方法中使用 this,而該方法在該對象的上下文中調(diào)用,那么 this 指代該對象本身。
你會說“在該對象的上下文中調(diào)用”……是啥意思?
別著急,我們一會兒就說。
所以,如果我們想從 greeting 中調(diào)用 getDaysUntilBirtyday 我們只需要寫 this.getDaysUntilBirthday,因為此時的 this 就是對象本身。
附注:不要在全局作用域的普通函數(shù)或另一個函數(shù)的作用域中使用 this!this 是個面向?qū)ο蟮臇|西,它只在對象的上下文(或類的上下文)中有意義。
我們利用 this 來重寫 initializeFriend:
function initializeFriend(data) { return { lastTenPosts: data.lastTenPosts, birthday: data.birthday, fullName: `${data.firstName} ${data.lastName}`, getThreeRandomPosts: function() { // get three random posts from this.lastTenPosts }, getDaysUntilBirthday: function() { // use this.birthday to get the num days until birthday }, greeting: function() { const numDays=this.getDaysUntilBirthday() return `Hello, this is ${this.fullName}'s data! It is ${numDays} until ${this.fullName}'s birthday!` } }; }
現(xiàn)在,在 initializeFriend 執(zhí)行結(jié)束后,該對象需要的一切都位于對象本身的作用域之內(nèi)了。我們的方法不需要再依賴于閉包,它們只會用到對象本身包含的信息。
好吧,這是 this 的用法之一,但你說過 this 在不同的上下文中有不同的含義。那是什么意思?為什么不一定會指向?qū)ο笞约海?/p>
有時候,你需要將 this 指向某個特定的東西。一種情況就是事件處理函數(shù)。比如我們希望在用戶點擊好友時打開好友的 Facebook 首頁。我們會給對象添加下面的 onClick 方法:
function initializeFriend(data) { return { lastTenPosts: data.lastTenPosts, birthday: data.birthday, username: data.username, fullName: `${data.firstName} ${data.lastName}`, getThreeRandomPosts: function() { // get three random posts from this.lastTenPosts }, getDaysUntilBirthday: function() { // use this.birthday to get the num days until birthday }, greeting: function() { const numDays=this.getDaysUntilBirthday() return `Hello, this is ${this.fullName}'s data! It is ${numDays} until ${this.fullName}'s birthday!` }, onFriendClick: function() { window.open(`https://facebook.com/${this.username}`) } }; }
注意我們在對象中添加了 username 屬性,這樣 onFriendClick 就能訪問它,從而在新窗口中打開該好友的 Facebook 首頁。現(xiàn)在只需要編寫 HTML:
<button id="Bob_Ross"> <!-- A bunch of info associated with Bob Ross --> </button>
還有 JavaScript:
const bobRossObj=initializeFriend(data[0]) const bobRossDOMEl=document.getElementById('Bob_Ross') bobRossDOMEl.addEventListener("onclick", bobRossObj.onFriendClick)
在上述代碼中,我們給 Bob Ross 創(chuàng)建了一個對象。然后我們拿到了 Bob Ross 對應(yīng)的 DOM 元素。然后執(zhí)行 onFriendClick 方法來打開 Bob 的 Facebook 主頁。似乎沒問題,對吧?
有問題!
哪里出錯了?
注意我們調(diào)用 onclick 處理程序的代碼是 bobRossObj.onFriendClick。看到問題了嗎?要是寫成這樣的話能看出來嗎?
bobRossDOMEl.addEventListener("onclick", function() { window.open(`https://facebook.com/${this.username}`) })
現(xiàn)在看到問題了嗎?如果把事件處理程序?qū)懗?bobRossObj.onFriendClick,實際上是把 bobRossObj.onFriendClick 上保存的函數(shù)拿出來,然后作為參數(shù)傳遞。它不再“依附”在 bobRossObj 上,也就是說,this 不再指向 bobRossObj。它實際指向全局對象,也就是說 this.username 不存在。似乎我們沒什么辦法了。
輪到綁定上場了!
7. 明確綁定 this
我們需要明確地將 this 綁定到 bobRossObj 上。我們可以通過 bind 實現(xiàn):
const bobRossObj=initializeFriend(data[0]) const bobRossDOMEl=document.getElementById('Bob_Ross') bobRossObj.onFriendClick=bobRossObj.onFriendClick.bind(bobRossObj) bobRossDOMEl.addEventListener("onclick", bobRossObj.onFriendClick)
之前,this 是按照默認(rèn)的規(guī)則設(shè)置的。但使用 bind 之后,我們明確地將 bobRossObj.onFriendClick 中的 this 的值設(shè)置為 bobRossObj 對象本身。
到此為止,我們看到了為什么要使用 this,以及為什么要明確地綁定 this。最后我們來介紹一下,this 實際上是箭頭函數(shù)。
8. 箭頭函數(shù)
你也許注意到了箭頭函數(shù)最近很流行。人們喜歡箭頭函數(shù),因為很簡潔、很優(yōu)雅。而且你還知道箭頭函數(shù)和普通函數(shù)有點區(qū)別,盡管不太清楚具體區(qū)別是什么。
簡而言之,兩者的區(qū)別在于:
在定義箭頭函數(shù)時,不管 this 指向誰,箭頭函數(shù)內(nèi)部的 this 永遠(yuǎn)指向同一個東西。
嗯……這貌似沒什么用……似乎跟普通函數(shù)的行為一樣啊?
我們通過 initializeFriend 舉例說明。假設(shè)我們想添加一個名為 greeting 的函數(shù):
function initializeFriend(data) { return { lastTenPosts: data.lastTenPosts, birthday: data.birthday, username: data.username, fullName: `${data.firstName} ${data.lastName}`, getThreeRandomPosts: function() { // get three random posts from this.lastTenPosts }, getDaysUntilBirthday: function() { // use this.birthday to get the num days until birthday }, greeting: function() { function getLastPost() { return this.lastTenPosts[0] } const lastPost=getLastPost() return `Hello, this is ${this.fullName}'s data! ${this.fullName}'s last post was ${lastPost}.` }, onFriendClick: function() { window.open(`https://facebook.com/${this.username}`) } }; }
這樣能運行嗎?如果不能,怎樣修改才能運行?
答案是不能。因為 getLastPost 沒有在對象的上下文中調(diào)用,因此getLastPost 中的 this 按照默認(rèn)規(guī)則指向了全局對象。
你說沒有“在對象的上下文中調(diào)用”……難道它不是從 initializeFriend 返回的內(nèi)部調(diào)用的嗎?如果這還不叫“在對象的上下文中調(diào)用”,那我就不知道什么才算了。
我知道“在對象的上下文中調(diào)用”這個術(shù)語很模糊。也許,判斷函數(shù)是否“在對象的上下文中調(diào)用”的好方法就是檢查一遍函數(shù)的調(diào)用過程,看看是否有個對象“依附”到了函數(shù)上。
我們來檢查下執(zhí)行 bobRossObj.onFriendClick() 時的情況。“給我對象 bobRossObj,找到其中的 onFriendClick 然后調(diào)用該屬性對應(yīng)的函數(shù)”。
我們同樣檢查下執(zhí)行 getLastPost() 時的情況。“給我名為 getLastPost 的函數(shù)然后執(zhí)行。”看到了嗎?我們根本沒有提到對象。
好了,這里有個難題來測試你的理解程度。假設(shè)有個函數(shù)名為 functionCaller,它的功能就是調(diào)用一個函數(shù):
functionCaller(fn) { fn() }
如果調(diào)用 functionCaller(bobRossObj.onFriendClick) 會怎樣?你會認(rèn)為 onFriendClick 是“在對象的上下文中調(diào)用”的嗎?this.username有定義嗎?
我們來檢查一遍:“給我 bobRosObj 對象然后查找其屬性 onFriendClick。取出其中的值(這個值碰巧是個函數(shù)),然后將它傳遞給 functionCaller,取名為 fn。然后,執(zhí)行名為 fn 的函數(shù)。”注意該函數(shù)在調(diào)用之前已經(jīng)從 bobRossObj 對象上“脫離”了,因此并不是“在對象的上下文中調(diào)用”的,所以 this.username 沒有定義。
這時可以用箭頭函數(shù)解決這個問題:
function initializeFriend(data) { return { lastTenPosts: data.lastTenPosts, birthday: data.birthday, username: data.username, fullName: `${data.firstName} ${data.lastName}`, getThreeRandomPosts: function() { // get three random posts from this.lastTenPosts }, getDaysUntilBirthday: function() { // use this.birthday to get the num days until birthday }, greeting: function() { const getLastPost=()=> { return this.lastTenPosts[0] } const lastPost=getLastPost() return `Hello, this is ${this.fullName}'s data! ${this.fullName}'s last post was ${lastPost}.` }, onFriendClick: function() { window.open(`https://facebook.com/${this.username}`) } }; }
上述代碼的規(guī)則是:
在定義箭頭函數(shù)時,不管 this 指向誰,箭頭函數(shù)內(nèi)部的 this 永遠(yuǎn)指向同一個東西。
箭頭函數(shù)是在 greeting 中定義的。我們知道,在 greeting 內(nèi)部的 this 指向?qū)ο蟊旧怼R虼耍^函數(shù)內(nèi)部的 this 也指向?qū)ο蟊旧恚@正是我們需要的結(jié)果。
9. 結(jié)論
this 有時很不好理解,但它對于開發(fā) JavaScript 應(yīng)用非常有用。本文當(dāng)然沒能介紹 this 的所有方面。一些沒有涉及到的話題包括:
我建議你首先問問自己在這些情況下的 this,然后在瀏覽器中執(zhí)行代碼來檢驗?zāi)愕慕Y(jié)果。
原文地址:https://mp.weixin.qq.com/s/L9eac6rzkSE_JqxXyg3FQw
么是JS延遲加載?
JS延遲加載,也就是等頁面加載完成之后再加載JavaScript文件
為什么讓JS實現(xiàn)延遲加載?
js的延遲加載有助于提高頁面的加載速度。
Js延遲加載的方式有哪些?一般有以下幾種方式:
·defer屬性
·async屬性
·動態(tài)創(chuàng)建DOM方式
·使用jQuery的getScript方法
·使用setTimeout延遲方法
·讓JS最后加載
HTML 4.01為<script>標(biāo)簽定義了defer屬性。標(biāo)簽定義了defer屬性元素中設(shè)置defer屬性,等于告訴瀏覽器立即下載,但延遲執(zhí)行標(biāo)簽定義了defer屬性。
用途:表明腳本在執(zhí)行時不會影響頁面的構(gòu)造。也就是說,腳本會被延遲到整個頁面都解析完畢之后再執(zhí)行在<script>元素中設(shè)置defer屬性,等于告訴瀏覽器立即下載,但延遲執(zhí)行
<!DOCTYPE html>
<html>
<head>
<script src="test1.js" defer="defer"></script>
<script src="test2.js" defer="defer"></script>
</head>
<body>
<!--這里放內(nèi)容-->
</body>
</html>
說明:雖然<script>元素放在了<head>元素中,但包含的腳本將延遲瀏覽器遇到</html>標(biāo)簽后再執(zhí)行HTML5規(guī)范要求腳本按照它們出現(xiàn)的先后順序執(zhí)行。在現(xiàn)實當(dāng)中,延遲腳本并不一定會按照順序執(zhí)行defer屬性只適用于外部腳本文件。支持HTML5的實現(xiàn)會忽略嵌入腳本設(shè)置的defer屬性
HTML5 為<script>標(biāo)簽定義了async屬性。與defer屬性類似,都用于改變處理腳本的行為。同樣,只適用于外部腳本文件。標(biāo)簽定義了async屬性。與defer屬性類似,都用于改變處理腳本的行為。同樣,只適用于外部腳本文件。
目的:不讓頁面等待腳本下載和執(zhí)行,從而異步加載頁面其他內(nèi)容。異步腳本一定會在頁面 load 事件前執(zhí)行。不能保證腳本會按順序執(zhí)行
<!DOCTYPE html>
<html>
<head>
<script src="test1.js" async></script>
<script src="test2.js" async></script>
</head>
<body>
<!--這里放內(nèi)容-->
</body>
</html>
async和defer一樣,都不會阻塞其他資源下載,所以不會影響頁面的加載。
缺點:不能控制加載的順序
//這些代碼應(yīng)被放置在</ body>標(biāo)簽前(接近HTML文件底部)
<script type="text/javascript">
function downloadJSAtOnload() {
varelement=document .createElement("script");
element.src="defer.js";
document.body.appendChild(element);
}
if (window. addEventListener)
window.addEventListener("load" ,downloadJSAtOnload, false);
else if (window.attachEvent)
window.attachEvent("onload", downloadJSAtOnload) ;
else
window. onload=downloadJSAtOnload;
</script>
$.getScript("outer.js" , function(){ //回調(diào)函數(shù),成功獲取文件后執(zhí)行的函數(shù)
console.log(“腳本加載完成")
});
<script type="text/javascript" >
function A(){
$.post("/1ord/1ogin" ,{name:username,pwd:password},function(){
alert("Hello");
});
}
$(function (){
setTimeout('A()', 1000); //延遲1秒
})
</script>
把js外部引入的文件放到頁面底部,來讓js最后引入,從而加快頁面加載速度例如引入外部js腳本文件時,如果放入html的head中,則頁面加載前該js腳本就會被加載入頁面,而放入body中,則會按照頁面從上倒下的加載順序來運行JavaScript的代碼。所以我們可以把js外部引入的文件放到頁面底部,來讓js最后引入,從而加快頁面加載速度。
上述方法2也會偶爾讓你收到Google頁面速度測試工具的“延遲加載javascript”警告。所以這里的解決方案將是來自Google幫助頁面的推薦方案。
//這些代碼應(yīng)被放置在</body>標(biāo)簽前(接近HTML文件底部)
<script type="text/javascript">
function downloadJSAtonload() {
var element=document.createElement("script");
element.src="defer.js";
document.body.appendChild(element);
}
if (window.addEventListener)
window.addEventListener("load", downloadJSAtOnload, false);
else if (window.attachEvent )
window.attachEvent("onload", downloadJSAtonload);
else window.onload=downloadJSAtOnload;
</script>
這段代碼意思等到整個文檔加載完后,再加載外部文件“defer.js”。
使用此段代碼的步驟:
6.1)復(fù)制上面代碼
6.2)粘貼代碼到HTML的標(biāo)簽前 (靠近HTML文件底部)
6.3)修改“defer.js”為你的外部JS文件名
6.4)確保文件路徑是正確的。例如:如果你僅輸入“defer.js”,那么“defer.js”文件一定與HTML文件在同一文件夾下。
注意:
這段代碼直到文檔加載完才會加載指定的外部js文件。因此,不應(yīng)該把那些頁面正常加載需要依賴的javascript代碼放在這里。而應(yīng)該將JavaScript代碼分成兩組。一組是因頁面需要而立即加載的javascript代碼,另外一組是在頁面加載后進(jìn)行操作的javascript代碼(例如添加click事件。
avascript原生阻止冒泡
<html>
<head>
<style type="text/css">
#hide{width:75%;height:80px;background:skyblue;display:block;}
.hander{cursor:pointer;}
input{margin:5 0 0 900;}
</style>
<script>
//不用window.onload也可以
document.documentElement.onclick=function() {
document.getElementById('hide').style.display='none';
}
//阻止冒泡事件方法
function stopBubble(e) {
e=e || window.event;
if(e.stopPropagation) { //W3C阻止冒泡方法
e.stopPropagation();
} else {
e.cancelBubble=true; //IE阻止冒泡方法
}
}
//方法必須要放在window.onload下
window.onload=function(){
document.getElementById("hide").onclick=function(e) {
stopBubble(e);
}
document.getElementById('btn_show').onclick=function(e) {
document.getElementById('hide').style.display='block';
stopBubble(e);
}
}
</script>
</head>
<body>
<div id="hide" class="hander">click here nothing happen,you can click beside this area</div>
<input type="button" id="btn_show" value="show" class="hander"/>
</body>
onclick 如何阻止事件冒泡
<div id="id_tag_list"><span class="right">▼</span><span class="label" onclick="deleteLabel(this)">Python數(shù)據(jù)分析與應(yīng)用</span></div>
//刪除標(biāo)簽的方法
function deleteLabel(target){
var e=target;
if(e && e.stopPropagation){ //阻止冒泡
// 因此它支持W3C的stopPropation()方法
e.stopPropagation();
}else{
// 否則, 我們得使用IE的方法來取消事件冒泡
window.event.cancelBubble=true;
}
}
jQuery如何阻止事件冒泡
<div class="subcategories">這里有點擊事件</div>
<div class="subcategories">這里有點擊事件</div>
<div class="subcategories">這里有點擊事件</div>
<script type="text/javascript">
//阻止點擊事件
$(function() {
$(".subcategories").click(function(event) {
event.stopPropagation();
});
});
</script>
什么是js事件冒泡?
在一個對象上觸發(fā)某類事件(比如單擊onclick事件), 如果此對象定義了此事件的處理程序, 那么此事件就會調(diào)用這個處理程序, 如果沒有定義此事件處理程序或者事件返回true,
那么這個事件會向這個對象的父級對象傳播, 從里到外, 直至它被處理(父級對象所有同類事件都將被激活), 或者它到達(dá)了對象層次的最頂層, 即document對象(有些瀏覽器是window)。
如何來阻止Jquery事件冒泡?
<!DOCTYPE html>
<html">
<head runat="server">
<title>Jquery 事件冒泡</title>
<script src="jquery-1.3.2-vsdoc.js" type="text/javascript"></script>
</head>
<body>
<form id="form1" runat="server">
<div id="divOne" onclick="alert('我是最外層');">
<div id="divTwo" onclick="alert('我是中間層!')">
<a id="hr_three" href="http://www.xxxxxx.com" mce_href="http://www.xxxxxx.com"onclick="alert('我是最里層!')">點擊我</a>
</div>
</div>
</form>
</body>
</html>
比如上面這個頁面,
分為三層:divOne是第外層,divTwo中間層,hr_three是最里層;
他們都有各自的click事件,最里層a標(biāo)簽還有href屬性。
運行頁面,點擊“點擊我”,會依次彈出:我是最里層---->我是中間層---->我是最外層
---->然后再鏈接到百度.
這就是事件冒泡, 本來我只點擊ID為hr_three的標(biāo)簽, 但是確執(zhí)行了三個alert操作。
事件冒泡過程(以標(biāo)簽ID表示):hr_three----> divTwo----> divOne 。從最里層冒泡到最外層。
如何來阻止?
1.event.stopPropagation();
<script type="text/javascript">
$(function() {
$("#hr_three").click(function(event) {
event.stopPropagation();
});
});
<script>
再點擊"點擊我", 會彈出:我是最里層, 然后鏈接到百度
2.return false;
如果頭部加入的是以下代碼
<script type="text/javascript">
$(function() {
$("#hr_three").click(function(event) {
return false;
});
});
<script>
再點擊"點擊我", 會彈出:我是最里層, 但不會執(zhí)行鏈接到百度頁面
由此可以看出:
1.event.stopPropagation();
事件處理過程中,阻止了事件冒泡,但不會阻擊默認(rèn)行為(它就執(zhí)行了超鏈接的跳轉(zhuǎn))
2.return false;
事件處理過程中,阻止了事件冒泡,也阻止了默認(rèn)行為(比如剛才它就沒有執(zhí)行超鏈接的跳轉(zhuǎn))
還有一種有冒泡有關(guān)的:
3.event.preventDefault();
如果把它放在頭部A標(biāo)簽的click事件中, 點擊"點擊我"。
會發(fā)現(xiàn)它依次彈出:我是最里層---->我是中間層---->我是最外層, 但最后卻沒有跳轉(zhuǎn)到百度
它的作用是:事件處理過程中, 不阻擊事件冒泡, 但阻擊默認(rèn)行為(它只執(zhí)行所有彈框, 卻沒有執(zhí)行超鏈接跳轉(zhuǎn))
*請認(rèn)真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。