以下為本站文章分類清單

  1. AJAXspacer
  2. ASPspacer
  3. CSSspacer
  4. Javascriptspacer
  5. Windows 應用程式spacer
  6. 網頁設計
  7. 評論、短文、雜文spacer
  8. 版主spacer
  9. 最新回應spacer

以下為本頁本文內容

addEventListener、attachEvent 和 this 關鍵字

8/23 10' icon

Photo by www.customicondesign.com/

如果你是為了 IE 的 attachEvent 不能使用 this 關鍵字而來的,試著把 handler 裡的 this 改成 event.srcElement 就可以了, ex:obj.attachEvent('onfocus',function(){event.srcElement.select();});,然後,快回去趕案子吧。

事件與控制

為事件(Event)加上控制(handler),是個常用設計,舉個例子來說,假設有個文字欄位,操作時希望選取這個欄位時,欄位值會自動選取(反白),以方便新數值鍵入。看起來像

內容很簡單,就是為 onclick 和 onfocus 這兩個事件加入控制,看起來像:

<input type="text" value="click" name="txt" id="txt"
	onclick="this.select();"
	onfocus="this.select();" />

好了,一份 HTML 文件中,如果有個十來個這種欄位,可能開始有人想用 javascript 來為每個欄位加入這些事件控制,於是我們需要的語法是 addEventListener (Firefox、Chrome、Safari、Opera) 或 attachEvent (IE),語法為:

if (window.addEventListener){
	//Mozilla 事件沒有 on 開頭
	window.addEventListener('load',helloAudi, false);
}else if (window.attachEvent){
	window.attachEvent('onload',helloAudi);
}

function helloAudi(){
	.....
}

function helloAudi_1(msg){
	alert(msg);
}

handlerName 是一個 function,把 function 的名稱寫進去即可,如上例,不用加括號。但,這個寫法,不可以加參數,也就是不能傳遞參數到 helloAudi() 中,例如要加入 helloAudi_1 時,那寫法改一下,在 handlerName 這裡直接使用 function() 陳述,如:

if (window.addEventListener){
	//Mozilla 事件沒有 on 開頭
	window.addEventListener('load',function(){helloAudi_1('謝謝');}, false);
}else if (window.attachEvent){
	window.attachEvent('onload',function(){helloAudi_1('謝謝');});
}

當然你可以為其他物件的事件加入控制,例如一開始提到的 this.select() 一樣

var obj=document.getElementById('txt');
if (window.addEventListener){
	obj.addEventListener('focus',function(){this.select();}, false);
	obj.addEventListener('click',function(){this.select();}, false);
}else if (window.attachEvent){
	obj.attachEvent('onfocus',function(){this.select();});
	obj.attachEvent('onclick',function(){this.select();});
}

本來,事情到這裡就結束了,不過實作卻發現,在 IE 上,this 關鍵字失效,正確的說,是 this 關鍵字不再是代表我們所認知的那個物件,而是統一指向最上層的 window 物件

<input type="text" value="click" name="txt1" id="txt1" />

<script type="text/javascript">
var obj=document.getElementById('txt1');
if (window.addEventListener){
	obj.addEventListener('click',function(){alert(this.id);}, false);
}else if (window.attachEvent){
	obj.attachEvent('onclick',function(){alert(this.id);});
}

上面的例子,在 Firefox / Chrome / IE9 下執行均顯示 txt1,在 IE9 以前的 IE 版本,則顯示 undefined。原因很簡單,對 this 的解讀不同。

this 關鍵字

this 是個有趣的關鍵字,是一種很口語化的關鍵字,但也讓很多人搞混,要了解 this 關鍵字,由生活中去體會即可,舉例來說

好了,相信你能舉一反三了,在生活中,很多情況,我們不需要再明確指定目標,而是簡單用"這個"、"這裡"、"這O"來代替就很清楚能指出想表達的物件。

同樣的,在程式語言裡,this 也有相同功效,例如:

<img src="hello.jpg" onmouseover="this.src='hello1.jpg';" />

試著用口語把上述內容說出來

影像 來源是hello.jpg 在滑鼠移過去時="這個來源是hello1.jpg"

以一句比較學術的話來說明 this

this 代表目前所處物件或正作用中物件

既然你身在其中,當然用"這個"就能代表想指定的物件,而不需要大費周折指定物件名稱或id等,同理延伸,要指定作用物件以外的物件,就必需清楚而明確的給予定義,例如使用 document.getElementById(id) 或流行的 $('#id')

IE 在搞什麼?

回到一開始的問題,透過 attachEvent,在參數中使用 this 為什麼失效呢?理由很簡單,就是認定"作用中物件"不同,IE 認為執行 window.attachEvent 動作時,作用中物件是 window,所以 this 也就代表 window,也就是,在指定事件時,IE 把整個物件代入到 this 關鍵字中,而非謹謹是把 this 這個字寫入事件裡,因此造成和設計者想像有所不同。

這種解讀也不能算錯,只不過和直觀的設計有所不同,但 DOM 裡實際上存在很多類似情況,也就是不知道現在"作用中物件"是那一個,類似的情況,在"避免子物件的 onclick 事件同時引發父物件事件"這篇文章中有比較詳細說明。

 

以下為文章回應區

同意轉載,不過麻煩看一下轉載需知

How do you treat a sore Achilles tendon?   2017/7/22 下午 03:12:00

Aw, this was a very nice post. Taking a few minutes and actual effort to create a good article… but what
can I say… I procrastinate a lot and never
seem to get nearly anything done.

What causes the heels of your feet to burn?   2017/7/21 下午 09:56:00

Hi to every single one, it's really a nice for me to go to see this web site, it includes precious Information.

foot pain bunion   2017/7/3 上午 10:05:00

Loving the info on this website, you have done outstanding job on the content.

foot pain exercises   2017/7/2 下午 04:46:00

Thanks for finally writing about >【卜維丰】addEventListener、attachEvent 和 this 關鍵字
<Liked it!

manicure   2017/5/4 上午 04:14:00

Attractive part of content. I just stumbled upon your website
and in accession capital to say that I get actually loved account your
weblog posts. Any way I will be subscribing for your feeds or even I fulfillment you
get admission to constantly fast.

manicure   2017/4/11 下午 06:31:00

Woah! I'm really digging the template/theme of this site.
It's simple, yet effective. A lot of times it's challenging to
get that "perfect balance" between superb usability and appearance.
I must say you've done a great job with this. Additionally, the blog loads very fast for me on Safari.
Excellent Blog!

給個回應
姓名:
佈落格網址:
  如果您是要發問問題, 最好有個問題測試的網址, 這樣比較容易找到您問題所在, 謝謝
內容: