成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

JavaScript 編程精解 中文第三版 十五、處理事件

Clect / 508人閱讀

摘要:事件與節(jié)點(diǎn)每個(gè)瀏覽器事件處理器被注冊在上下文中。事件對(duì)象雖然目前為止我們忽略了它,事件處理器函數(shù)作為對(duì)象傳遞事件對(duì)象。若事件處理器不希望執(zhí)行默認(rèn)行為通常是因?yàn)橐呀?jīng)處理了該事件,會(huì)調(diào)用事件對(duì)象的方法。

來源:ApacheCN『JavaScript 編程精解 中文第三版』翻譯項(xiàng)目

原文:Handling Events

譯者:飛龍

協(xié)議:CC BY-NC-SA 4.0

自豪地采用谷歌翻譯

部分參考了《JavaScript 編程精解(第 2 版)》

你對(duì)你的大腦擁有控制權(quán),而不是外部事件。認(rèn)識(shí)到這一點(diǎn),你就找到了力量。

馬可·奧勒留,《沉思錄》

有些程序處理用戶的直接輸入,比如鼠標(biāo)和鍵盤動(dòng)作。這種輸入方式不是組織整齊的數(shù)據(jù)結(jié)構(gòu) - 它是一次一個(gè)地,實(shí)時(shí)地出現(xiàn)的,并且期望程序在發(fā)生時(shí)作出響應(yīng)。

事件處理器

想象一下,有一個(gè)接口,若想知道鍵盤上是否有一個(gè)鍵是否被按下,唯一的方法是讀取那個(gè)按鍵的當(dāng)前狀態(tài)。為了能夠響應(yīng)按鍵動(dòng)作,你需要不斷讀取鍵盤狀態(tài),以在按鍵被釋放之前捕捉到按下狀態(tài)。這種方法在執(zhí)行時(shí)間密集計(jì)算時(shí)非常危險(xiǎn),因?yàn)槟憧赡苠e(cuò)過按鍵事件。

一些原始機(jī)器可以像那樣處理輸入。有一種更進(jìn)一步的方法,硬件或操作系統(tǒng)發(fā)現(xiàn)按鍵時(shí)間并將其放入隊(duì)列中。程序可以周期性地檢查隊(duì)列,等待新事件并在發(fā)現(xiàn)事件時(shí)進(jìn)行響應(yīng)。

當(dāng)然,程序必須記得監(jiān)視隊(duì)列,并經(jīng)常做這種事,因?yàn)槿魏螘r(shí)候,按鍵被按下和程序發(fā)現(xiàn)事件之間都會(huì)使得軟件反應(yīng)遲鈍。該方法被稱為輪詢。大多數(shù)程序員更希望避免這種方法。

一個(gè)更好的機(jī)制是,系統(tǒng)在發(fā)生事件時(shí)主動(dòng)通知我們的代碼。瀏覽器實(shí)現(xiàn)了這種特性,支持我們將函數(shù)注冊為特定事件的處理器。

Click this document to activate the handler.

window綁定指向?yàn)g覽器提供的內(nèi)置對(duì)象。 它代表包含文檔的瀏覽器窗口。 調(diào)用它的addEventListener方法注冊第二個(gè)參數(shù),以便在第一個(gè)參數(shù)描述的事件發(fā)生時(shí)調(diào)用它。

事件與 DOM 節(jié)點(diǎn)

每個(gè)瀏覽器事件處理器被注冊在上下文中。在為整個(gè)窗口注冊處理器之前,我們在window對(duì)象上調(diào)用了addEventListener。 這種方法也可以在 DOM 元素和一些其他類型的對(duì)象上找到。 僅當(dāng)事件發(fā)生在其注冊對(duì)象的上下文中時(shí),才調(diào)用事件監(jiān)聽器。


No handler here.

示例代碼中將處理器附加到按鈕節(jié)點(diǎn)上。因此,點(diǎn)擊按鈕時(shí)會(huì)觸發(fā)并執(zhí)行處理器,而點(diǎn)擊文檔的其他部分則沒有反應(yīng)。

向節(jié)點(diǎn)提供onclick屬性也有類似效果。這適用于大多數(shù)類型的事件 - 您可以為屬性附加處理器,屬性名稱為前面帶有on的事件名稱。

但是一個(gè)節(jié)點(diǎn)只能有一個(gè)onclick屬性,所以你只能用這種方式為每個(gè)節(jié)點(diǎn)注冊一個(gè)處理器。 addEventListener方法允許您添加任意數(shù)量的處理器,因此即使元素上已經(jīng)存在另一個(gè)處理器,添加處理器也是安全的。

removeEventListener方法將刪除一個(gè)處理器,使用類似于addEventListener的參數(shù)調(diào)用。


賦予removeEventListener的函數(shù)必須是賦予addEventListener的完全相同的函數(shù)值。 因此,要注銷一個(gè)處理其,您需要為該函數(shù)提供一個(gè)名稱(在本例中為once),以便能夠?qū)⑾嗤暮瘮?shù)值傳遞給這兩個(gè)方法。

事件對(duì)象

雖然目前為止我們忽略了它,事件處理器函數(shù)作為對(duì)象傳遞:事件(Event)對(duì)象。這個(gè)對(duì)象持有事件的額外信息。例如,如果我們想知道哪個(gè)鼠標(biāo)按鍵被按下,我們可以查看事件對(duì)象的which屬性。


存儲(chǔ)在各種類型事件對(duì)象中的信息是有差別的。隨后本章將會(huì)討論許多類型的事件。對(duì)象的type屬性一般持有一個(gè)字符串,表示事件(例如"click""mousedown")。

傳播

對(duì)于大多數(shù)事件類型,在具有子節(jié)點(diǎn)的節(jié)點(diǎn)上注冊的處理器,也將接收發(fā)生在子節(jié)點(diǎn)中的事件。若點(diǎn)擊一個(gè)段落中的按鈕,段落的事件處理器也會(huì)收到點(diǎn)擊事件。

但若段落和按鈕都有事件處理器,則先執(zhí)行最特殊的事件處理器(按鈕的事件處理器)。也就是說事件向外傳播,從觸發(fā)事件的節(jié)點(diǎn)到其父節(jié)點(diǎn),最后直到文檔根節(jié)點(diǎn)。最后,當(dāng)某個(gè)特定節(jié)點(diǎn)上注冊的所有事件處理器按其順序全部執(zhí)行完畢后,窗口對(duì)象的事件處理器才有機(jī)會(huì)響應(yīng)事件。

事件處理器任何時(shí)候都可以調(diào)用事件對(duì)象的stopPropagation方法,阻止事件進(jìn)一步傳播。該方法有時(shí)很實(shí)用,例如,你將一個(gè)按鈕放在另一個(gè)可點(diǎn)擊元素中,但你不希望點(diǎn)擊該按鈕會(huì)激活外部元素的點(diǎn)擊行為。

下面的示例代碼將mousedown處理器注冊到按鈕和其外部的段落節(jié)點(diǎn)上。在按鈕上點(diǎn)擊鼠標(biāo)右鍵,按鈕的處理器會(huì)調(diào)用stopPropagation,調(diào)度段落上的事件處理器執(zhí)行。當(dāng)點(diǎn)擊鼠標(biāo)其他鍵時(shí),兩個(gè)處理器都會(huì)執(zhí)行。

A paragraph with a .

大多數(shù)事件對(duì)象都有target屬性,指的是事件來源節(jié)點(diǎn)。你可以根據(jù)該屬性防止無意中處理了傳播自其他節(jié)點(diǎn)的事件。

我們也可以使用target屬性來創(chuàng)建出特定類型事件的處理網(wǎng)絡(luò)。例如,如果一個(gè)節(jié)點(diǎn)中包含了很長的按鈕列表,比較方便的處理方式是在外部節(jié)點(diǎn)上注冊一個(gè)點(diǎn)擊事件處理器,并根據(jù)事件的target屬性來區(qū)分用戶按下了哪個(gè)按鈕,而不是為每個(gè)按鈕都注冊獨(dú)立的事件處理器。




默認(rèn)動(dòng)作

大多數(shù)事件都有與其關(guān)聯(lián)的默認(rèn)動(dòng)作。若點(diǎn)擊鏈接,就會(huì)跳轉(zhuǎn)到鏈接目標(biāo)。若點(diǎn)擊向下的箭頭,瀏覽器會(huì)向下翻頁。若右擊鼠標(biāo),可以得到一個(gè)上下文菜單等。

對(duì)于大多數(shù)類型的事件,JavaScript 事件處理器會(huì)在默認(rèn)行為發(fā)生之前調(diào)用。若事件處理器不希望執(zhí)行默認(rèn)行為(通常是因?yàn)橐呀?jīng)處理了該事件),會(huì)調(diào)用preventDefault事件對(duì)象的方法。

你可以實(shí)現(xiàn)你自己的鍵盤快捷鍵或交互式菜單。你也可以干擾用戶期望的行為。例如,這里實(shí)現(xiàn)一個(gè)無法跳轉(zhuǎn)的鏈接。

MDN

除非你有非常充足的理由,否則不要這樣做。當(dāng)預(yù)期的行為被打破時(shí),使用你的頁面的人會(huì)感到不快。

在有些瀏覽器中,你完全無法攔截某些事件。比如在 Chrome 中,關(guān)閉鍵盤快捷鍵(CTRL-WCOMMAND-W)無法由 JavaScript 處理。

按鍵事件

當(dāng)按下鍵盤上的按鍵時(shí),瀏覽器會(huì)觸發(fā)"keydown"事件。當(dāng)松開按鍵時(shí),會(huì)觸發(fā)"keyup"事件。

This page turns violet when you hold the V key.

盡管從keydown這個(gè)事件名上看應(yīng)該是物理按鍵按下時(shí)觸發(fā),但當(dāng)持續(xù)按下某個(gè)按鍵時(shí),會(huì)循環(huán)觸發(fā)該事件。有時(shí),你想謹(jǐn)慎對(duì)待它。例如,如果您在按下某個(gè)按鍵時(shí)向 DOM 添加按鈕,并且在釋放按鍵時(shí)再次將其刪除,則可能會(huì)在按住某個(gè)按鍵的時(shí)間過長時(shí),意外添加數(shù)百個(gè)按鈕。

該示例查看了事件對(duì)象的key屬性,來查看事件關(guān)于哪個(gè)鍵。 該屬性包含一個(gè)字符串,對(duì)于大多數(shù)鍵,它對(duì)應(yīng)于按下該鍵時(shí)將鍵入的內(nèi)容。 對(duì)于像Enter這樣的特殊鍵,它包含一個(gè)用于命名鍵的字符串(在本例中為"Enter")。 如果你按住一個(gè)鍵的同時(shí)按住Shift鍵,這也可能影響鍵的名稱 - "v"變?yōu)?b>"V","1"可能變成"!",這是按下Shift-1鍵 在鍵盤上產(chǎn)生的東西。

諸如shift、ctrlaltmeta(Mac 上的command)之類的修飾按鍵會(huì)像普通按鍵一樣產(chǎn)生事件。但在查找組合鍵時(shí),你也可以查看鍵盤和鼠標(biāo)事件的shiftKey、ctrlKey、altKeymetaKey屬性來判斷這些鍵是否被按下。

Press Ctrl-Space to continue.

按鍵事件發(fā)生的 DOM 節(jié)點(diǎn)取決于按下按鍵時(shí)具有焦點(diǎn)的元素。 大多數(shù)節(jié)點(diǎn)不能擁有焦點(diǎn),除非你給他們一個(gè)tabindex屬性,但像鏈接,按鈕和表單字段可以。 我們將在第 18 章中回顧表單字段。 當(dāng)沒有特別的焦點(diǎn)時(shí),document.body充當(dāng)按鍵事件的目標(biāo)節(jié)點(diǎn)。

當(dāng)用戶鍵入文本時(shí),使用按鍵事件來確定正在鍵入的內(nèi)容是有問題的。 某些平臺(tái),尤其是 Android 手機(jī)上的虛擬鍵盤,不會(huì)觸發(fā)按鍵事件。 但即使你有一個(gè)老式鍵盤,某些類型的文本輸入也不能直接匹配按鍵,例如其腳本不適合鍵盤的人所使用的 IME(“輸入法編輯器”)軟件 ,其中組合多個(gè)熱鍵來創(chuàng)建字符。

要注意什么時(shí)候輸入了內(nèi)容,每當(dāng)用戶更改其內(nèi)容時(shí),可以鍵入的元素(例如