Heim Web-Frontend js-Tutorial JavaScript Event学习第八章 事件的顺序_javascript技巧

JavaScript Event学习第八章 事件的顺序_javascript技巧

May 16, 2016 pm 06:35 PM
event Abfolge der Ereignisse

基本问题很简单。假设你的一个元素包含在另外一个元素中。

复制代码 代码如下:

-----------------------------------
| element1 |
| ------------------------- |
| |element2 | |
| ------------------------- |

-----------------------------------

这两个元素都有onclick事件处理程序。如果用户在element2上面单击那么在元素2和元素1上都触发了单击事件。但是哪个事件先发生呢?哪个事件处理程序会先执行呢?换句话说,事件顺序(event order)是什么呢?

两种模式
毫无疑问的,Netscape和微软在过去那段很糟糕的日子里都做出了自己的决定。
Netscape说element1先发生的。这叫事件捕获(event capturing)。
微软觉得element2先发生的。这叫事件冒泡(event bubbling)。
这两种事件顺序刚好相反。IE只支持事件冒泡。Mozilla,Opera 7和Konqueror两种都支持。早一些的Opear和iCab浏览器两个都不支持。

事件捕获
当你使用事件捕获的时候
复制代码 代码如下:


---------------| |-----------------
| element1 | | |
| --------- --| |----------- |
| |element2 \ / | |
| ------------------------- |
| Event CAPTURING |
-----------------------------------

element1的事件处理程序会先执行,element2后执行。

事件冒泡
但你使用事件冒泡的时候
复制代码 代码如下:

/ \
---------------| |-----------------
| element1 | | |
| ---------- -| |----------- |
| |element2 | | | |
| ------------------------- |
| Event BUBBLING |
-----------------------------------

element2的事件处理程序会先执行,element1的事件处理程序后执行。

W3C模式
W3C决定在这场战争中保持重力。在W3C事件模型中任何事件发生都是首先被捕获直到到达目标元素,然后再冒泡。
复制代码 代码如下:

| | / \
-----------------| |--| |-----------------
| element1 | | | | |
| ----------- --| |--| |----------- |
| |element2 \ / | | | |
| -------------------------------- |
| W3C event model |
------------------------------------------

作为设计师的你,可以随意选择把事件处理程序注册在捕获还是冒泡阶段。通过之前高级模式里面介绍的addEventListener()方法就可以完成。如果最后一个参数是true那么就设置成为事件捕获,如果是false就设置为事件冒泡。

假设你这样写
element1.addEventListener('click',doSomething2,true)
element2.addEventListener('click',doSomething,false)
如果用户在element2上单击就会发生下面的事情:
、click事件发生在捕获阶段。这样看来,如果element2的任何一个父元素有onclick事件处理程序那么都会执行。
、事件在element1上发现了doSomething2(),那么就会执行它。
、事件向下传递直到目标本身,再没有其他的捕获阶段程序了。事件转而进入冒泡阶段然后就会执行doSomething(),也就是element2注册在冒泡阶段的事件处理程序。
、事件再向上传递再检查是否有父元素在冒泡阶段设置事件处理程序。这里没有,所以什么也不会发生。
反过来:
element1.addEventListener('click',doSomething2,false)
element2.addEventListener('click',doSomething,false)

现在如果用户在element2上面点击就会发生:
、事件click发生在捕获阶段。事件会查找element2的父元素是否有在捕获阶段注册事件处理程序,在这里没有。
、事件向下传递直到目标本身。然后开始冒泡阶段,执行dosomething(),这个是注册在element2冒泡阶段的事件处理程序。
、事件继续向上传递然后检查是否有父元素在冒泡阶段注册了事件处理程序。
、事件发现了element1.然后doSomething2()就被执行了。

传统模式下的兼容性
对于那些支持W3C DOM的浏览器来说,传统的事件注册

element1.onclick = doSomething2;
就被看做是注册在冒泡阶段的。

事件冒泡的使用
很少有设计师意识到事件捕获或者冒泡。在网页制作的今天,貌似没必要让一个冒泡事件被一系列的事件处理程序来处理。用户也会在单击之后发生一系列事件而感到迷惑,通常你也想让你的事件处理程序的代码保持一定的独立性。当用户点击一个元素,发生了一些事情,当他单击其他元素,那么其他再发生其他事情。
当然在将来也许会改变,最好让模式向前兼容。但是如今最实用的事件捕获和冒泡就是默认函数的注册。

它总是会发生
首先你需要理解的就是事件捕获或者冒泡总是在发生的。如果你为你的整个页面定义了一个onclick事件:
复制代码 代码如下:

document.onclick = doSomething;
if (document.captureEvents) document.captureEvents(Event.CLICK);

你在任意元素上的click时间都会冒泡到页面然后出发了这个事件处理程序。只有当前面的事件处理程序明确的阻止冒泡,才不会传递到整个页面。

使用
因为每个事件都会在整个文档上停止,默认的事件处理程序就变得可能。假设你有一个这样的页面:
复制代码 代码如下:

------------------------------------
| document |
| --------------- ------------ |
| | element1 | | element2 | |
| --------------- ------------ |

------------------------------------

element1.onclick = doSomething;
element2.onclick = doSomething;
document.onclick = defaultFunction;

现在如果用户点击了element1或者element2那么doSomething()就会执行。在这如果你愿意也可以阻止他的传播。如果不的话,那么defaultFunction()就会执行。用户在其他地方的点击也会让defaultFunction()执行。有时候这可能有用。
设置全局的事件处理程序在写拖动代码的时候就很有必要。通常一个层上的mousedow事件会选择这个层然后对mousemove事件做出回应。虽然mousedown通常注册在这个层上来避免一些浏览器的bug,但是其他的事件处理程序都必须是全局的(document-wide)。
记住浏览器逻辑的第一定律:什么都会发生的,而且经常是在你做的准备最少的时候。可能发生的是用户的鼠标疯狂的移动然后代码没有跟上导致鼠标已经不再这个层上了。
如果在某个层上注册了onmousemove事件处理程序,如果这个层不再响应鼠标的移动了,那么肯定会让用户感到迷惑。
如果某个曾上注册了onmouseup事件处理程序,那么程序会在用户松开鼠标的时候程序没有捕捉到造成这个层还在随着鼠标移动。
在这种情况下事件冒泡就很重要,因为全局的事件处理程序会保证执行的。

关掉它
但是通常你想关闭所有的相关的捕获和冒泡。另外,如果你的文档结构非常的复杂(比如一大堆复杂的表格之类)你也需要关闭冒泡来节省系统资源。要不然浏览器就得一个个的查看父元素是否有事件处理程序。虽然可能一个都没有,但是查找一样浪费时间。
在微软模式里你必须讲事件的cancelBubble属性设置为true。
window.event.cancelBubble = true
在W3C模式中你必须调用stopPropagation()方法。

e.stopPropagation()
这会阻止这个事件的冒泡阶段。阻止事件的捕获极端基本上是不可能的。我也想知道为啥。
一个完整的跨浏览器的代码如下:
复制代码 代码如下:

function doSomething(e)
{
if (!e) var e = window.event;
e.cancelBubble = true;
if (e.stopPropagation) e.stopPropagation();
}

在不支持cancelBubble的浏览器里面设置也不会有啥问题。浏览器会创建一个这样的属性。当然是没啥用的,只是为了安全。

currentTarget
我们之前讲过,一个事件包含target或者srcElement包含一个发生事件的元素的引用。在我们的例子是element2,因为用户点击了他。
理解在捕获和冒泡过程中这个target是不会改变的非常重要:他一直指向element2.
但是假设我们注册了下面的事件处理程序:

element1.onclick = doSomething;
element2.onclick = doSomething;
如果用户点击element2那么doSomething()执行了两次。那么你怎样知道那个HTML元素处理着这个事件呢?target/scrElement也不能给出答案,从事件一开始就一直指向element2.
为了解决这个问题W3C添加了currentTarget属性。它包含一个正在处理的事件的HTML元素的引用:就是我们想要的那个。不幸的是微软模式没有类似的属性。
你也可以用this关键字。在这个例子里就是指向正在处理的事件的HTML元素,就先currentTarget。

微软模式的问题
但是当你使用微软的事件注册模型,this关键字不是只想HTML元素的。然后又没有一个像currentTarget类似的属性,这就意味着如果你这么做:

element1.attachEvent('onclick',doSomething)
element2.attachEvent('onclick',doSomething)
你就不知道那个HTML元素正在处理事件。这是微软的事件注册模式最严重的问题所以就根本不要用他,即使是那些只在IE/win下的程序。
我希望微软能够尽快添加一个类似currentTarget的属性或者遵循标准?我们设计急需啊。

继续
如果你想继续学习,请看下一章。
原文地址:http://www.quirksmode.org/js/events_order.html
我的twitter: @rehawk
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

Video Face Swap

Video Face Swap

Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Ereignisverarbeitungsbibliothek in PHP8.0: Ereignis Ereignisverarbeitungsbibliothek in PHP8.0: Ereignis May 14, 2023 pm 05:40 PM

Ereignisverarbeitungsbibliothek in PHP8.0: Ereignis Mit der kontinuierlichen Entwicklung des Internets wird PHP als beliebte Back-End-Programmiersprache häufig bei der Entwicklung verschiedener Webanwendungen verwendet. In diesem Prozess ist der ereignisgesteuerte Mechanismus zu einem sehr wichtigen Teil geworden. Die Ereignisverarbeitungsbibliothek Event in PHP8.0 bietet uns eine effizientere und flexiblere Ereignisverarbeitungsmethode. Was ist Event-Handling? Event-Handling ist ein sehr wichtiges Konzept bei der Entwicklung von Webanwendungen. Ereignisse können jede Art von Benutzerzeile sein

Steam Summer Sale – Valve verspricht 95 % Rabatt auf AAA-Spiele und bestätigt Rabatte für die viralen Spiele Palworld und Content Warning Steam Summer Sale – Valve verspricht 95 % Rabatt auf AAA-Spiele und bestätigt Rabatte für die viralen Spiele Palworld und Content Warning Jun 26, 2024 pm 03:40 PM

Beim Summer Sale von Steam gab es bereits einige der besten Spiele-Rabatte, und dieses Jahr scheint es für Valve ein weiteres Homerun-Angebot zu geben. Ein Trailer (siehe unten), der einige der im Steam Summer Sale reduzierten Spiele vorstellt, wurde gerade veröffentlicht

So verwenden Sie das Event-Ereignismodul von Pygame in Python So verwenden Sie das Event-Ereignismodul von Pygame in Python May 18, 2023 am 11:58 AM

Das Event-Modul von Pygame ist eines der wichtigen Module von Pygame. Es ist der Kern für die Erstellung des gesamten Spielprogramms, z. B. häufig verwendete Mausklicks, Tastaturtipps, Spielfensterbewegung, Fenstergrößenänderung, Auslösen bestimmter Plots und Beenden . Spiele usw., diese können als „Ereignisse“ angesehen werden. Der Ereignistyp Pygame definiert eine Struktur, die speziell zum Verarbeiten von Ereignissen verwendet wird, nämlich die Ereigniswarteschlange. Diese Struktur folgt dem Grundprinzip „Wer zuerst kommt, mahlt zuerst“. Über die Ereigniswarteschlange können wir Benutzervorgänge in einer geordneten Reihenfolge verarbeiten -nach-eins (Trigger-Ereignis). Die folgende Tabelle listet die häufig verwendeten Spielereignisse in Pygame auf: Name Beschreibung QUIT Der Benutzer drückt die Schaltfläche zum Schließen des Fensters ATIVEEVENTPy

Um welches Ereignis handelt es sich in JavaScript, wenn die Größe des Browserfensters geändert wird? Um welches Ereignis handelt es sich in JavaScript, wenn die Größe des Browserfensters geändert wird? Sep 05, 2023 am 11:25 AM

Verwenden Sie die Ereignisse window.outerWidth und window.outerHeight, um die Fenstergröße in JavaScript abzurufen, wenn die Größe des Browsers geändert wird. Beispiel: Sie können versuchen, den folgenden Code auszuführen, um die Größe des Browserfensters mithilfe von Ereignissen zu überprüfen: <!DOCTYPEhtml><html>

Steam Summer Sale-Trailer kündigt 95 % Rabatt auf AAA-Spieleangebote an und bestätigt Preissenkungen für Palworld, Stellaris und Content Warning Steam Summer Sale-Trailer kündigt 95 % Rabatt auf AAA-Spieleangebote an und bestätigt Preissenkungen für Palworld, Stellaris und Content Warning Jun 26, 2024 am 06:30 AM

Beim Summer Sale von Steam gab es bereits einige der besten Spiele-Rabatte, und dieses Jahr scheint es für Valve ein weiteres Homerun-Angebot zu geben. Ein Trailer (siehe unten), der einige der im Steam Summer Sale reduzierten Spiele vorstellt, wurde gerade veröffentlicht

Tesla verschickt Robotaxi-Einladungen für die Demoveranstaltung zum autonomen Fahren am 10. Oktober in LA Tesla verschickt Robotaxi-Einladungen für die Demoveranstaltung zum autonomen Fahren am 10. Oktober in LA Sep 27, 2024 am 06:20 AM

Ursprünglich wurde erwartet, dass Tesla sein zuvor durchgesickertes Robotaxi bereits im August dieses Jahres enthüllen würde, doch CEO Elon Musk verschob die Veranstaltung unter Berufung auf ästhetische Änderungen an der Vorderseite des Robotaxi und den zusätzlichen Zeitaufwand für einige Last-Minute-Vorgänge

Tesla Robotaxi gibt bekannt, dass es am 10. Oktober starten wird, während die Einladungen an ausgewählte Aktionäre verschickt werden Tesla Robotaxi gibt bekannt, dass es am 10. Oktober starten wird, während die Einladungen an ausgewählte Aktionäre verschickt werden Sep 26, 2024 pm 06:06 PM

Ursprünglich wurde erwartet, dass Tesla sein zuvor durchgesickertes Robotaxi bereits im August dieses Jahres enthüllen würde, doch CEO Elon Musk verschob die Veranstaltung unter Berufung auf ästhetische Änderungen an der Vorderseite des Robotaxi und den zusätzlichen Zeitaufwand für einige Last-Minute-Vorgänge

Verstehen Sie den Mechanismus der Ereignisausbreitung: Erfassung und Analyse der Blasenreihenfolge Verstehen Sie den Mechanismus der Ereignisausbreitung: Erfassung und Analyse der Blasenreihenfolge Feb 19, 2024 pm 07:11 PM

Sollten Ereignisse zuerst erfasst oder zuerst gesprudelt werden? Das Geheimnis der ereignisauslösenden Sequenz knacken Die Ereignisverarbeitung ist ein sehr wichtiger Teil der Webentwicklung, und die ereignisauslösende Sequenz ist eines der Geheimnisse. In HTML werden Ereignisse normalerweise durch „Capturing“ oder „Bubbling“ verbreitet. Was sollte zuerst eingefangen oder zuerst gesprudelt werden? Das ist eine sehr verwirrende Frage. Bevor wir diese Frage beantworten, wollen wir zunächst die „Einfang“- und „Blasen“-Mechanismen von Ereignissen verstehen. Unter Ereigniserfassung versteht man die schichtweise Weitergabe von Ereignissen von Elementen der obersten Ebene an Zielknoten, sodass Ereignisse in die Luft sprudeln

See all articles