Les événements sont le cœur battant des applications JavaScript et le ciment qui maintient tout ensemble. Des événements se produisent lorsque nous effectuons certains types d'interactions avec des pages Web dans le navigateur. Un événement peut être un utilisateur cliquant sur quelque chose, déplaçant la souris sur un élément spécifique ou appuyant sur certaines touches du clavier. Les événements peuvent également être des événements qui se produisent dans le navigateur Web, comme le chargement d'une page Web ou le défilement ou le redimensionnement de la fenêtre par l'utilisateur.
En utilisant JavaScript, vous pouvez écouter des événements spécifiques qui se produisent et spécifier que certains événements se produisent en réponse à ces événements.
Au cours de la longue histoire de l'évolution, nous avons fait nos adieux à la gestion des événements en ligne (en utilisant des gestionnaires d'événements directement dans les éléments HTML). Les événements d'aujourd'hui constituent déjà une partie importante du DOM. Malheureusement, IE continue de conserver le modèle d'événement implémenté pour la première fois dans IE4.0 et n'a pas apporté beaucoup de modifications dans les versions ultérieures d'IE. Cela signifie qu'IE utilise toujours un modèle d'événement propriétaire (. type de bulle), tandis que d'autres navigateurs grand public ne prenaient pas en charge le modèle de traitement d'événements standard du DOM - type de capture et type de bouillonnement - jusqu'à ce que les réglementations DOM niveau 3 soient finalisées.
La raison historique est la suivante : la spécification du W3C n'a défini aucun événement dans le niveau 1 du DOM. Ce n'est que lors de la sortie du niveau 2 du DOM en novembre 2000 qu'un petit sous-ensemble a été défini, qui est déjà fourni dans le niveau 2 du DOM. Afin de fournir un moyen plus détaillé et granulaire de contrôler les événements dans les pages Web, des événements complets ont finalement été finalisés dans la spécification DOM niveau 3 de 2004. Étant donné qu'IE4 a été lancé en 1995 et avait implémenté son propre modèle d'événement (type bulle), il n'existait pas de norme DOM à cette époque. Cependant, le modèle d'événement d'IE a été absorbé dans le processus de spécification de la norme DOM qui a suivi.
Actuellement, en plus du navigateur IE, d'autres Firefox, Opera et Safari grand public prennent tous en charge le modèle standard de traitement des événements DOM. IE utilise toujours son propre modèle d'événement propriétaire, c'est-à-dire le type bouillonnant. Une partie de son modèle d'événement est adoptée par la norme DOM. C'est également bon pour les développeurs. Ce n'est qu'en utilisant la norme
DOM qu'IE le partage. les méthodes de gestion peuvent être efficaces sur tous les navigateurs.
La structure DOM (Document Object Model) est une structure arborescente Lorsqu'un élément HTML génère un événement, l'événement sera pressé entre le nœud de l'élément et le nœud racine propagé. dans un ordre spécifique, tous les nœuds le long du chemin recevront l'événement. Ce processus de propagation peut être appelé flux d'événements DOM.
Il existe deux types de séquences d'événements : la capture d'événements et la diffusion d'événements.
Événements bouillonnants (Event Bubbling)
Il s'agit de l'implémentation du modèle d'événement par le navigateur IE, et c'est aussi la plus simple à comprendre, du moins l'auteur pense qu'elle est plus réaliste. Bouillonnant, comme son nom l’indique, les événements bouillonnent comme des bulles dans l’eau jusqu’à atteindre le sommet. Du point de vue de la structure arborescente DOM, les événements sont transmis des nœuds feuilles jusqu'au nœud racine le long des nœuds ancêtres ; à partir du niveau de disposition des éléments HTML de la vue de l'interface du navigateur, les événements sont transmis de l'élément cible le plus certain avec une relation subordonnée à l'élément cible. élément cible le plus incertain. Technologie bouillonnante. L'idée de base des événements bouillonnants commence à partir d'une cible d'événement spécifique jusqu'à la cible d'événement la plus incertaine.
Capture d'événements (Event Capturing)
Netscape. L'implémentation est juste à l'opposé du type bouillonnant, en commençant par l'élément le plus haut de l'arborescence DOM jusqu'à l'élément le plus précis. Ce modèle d'événement est un peu déroutant pour les développeurs (du moins moi...) car intuitivement, la compréhension devrait être la même. type bouillonnant, et la transmission de l'événement doit commencer à partir de l'élément le plus certain, c'est-à-dire l'élément générateur d'événement.
Modèle d'événement standard DOM
Nous avons expliqué et comparé les deux modèles d'événements différents ci-dessus. La norme DOM prend en charge deux modèles d'événements en même temps, à savoir la capture d'événements et les événements bouillonnants. Cependant, la capture des événements se produit en premier. Les deux flux d'événements déclencheront tous les objets du DOM, en commençant par l'objet document et en terminant par l'objet document (la plupart des navigateurs conformes aux normes continueront à capturer/buller les événements dans l'objet fenêtre).
Comme le montre la figure : il y a d'abord l'événement de livraison de type capture, puis la livraison de type bouillonnant. Par conséquent, si une fonction de traitement enregistre à la fois l'écouteur d'événement de type capture. et l'événement de type bulle Écoute d'événement Bubble, il sera alors appelé deux fois dans le modèle d'événement DOM.
La caractéristique la plus unique du modèle d'événement standard DOM est que les nœuds de texte déclencheront également des événements (pas dans IE).
Event Delivery
Afin de mieux expliquer le principe du flux d'événements dans le standard DOM, nous l'avons mis dans le résumé "Event Delivery" pour être plus explication précise.
Évidemment, si un écouteur d'événement de clic est ajouté à un lien hypertexte, l'écouteur d'événement sera exécuté lorsque le lien sera cliqué. Mais si l'écouteur d'événement est affecté à l'élément p contenant le lien ou au nœud de document en haut de l'arborescence DOM, alors cliquer sur le lien déclenchera également l'écouteur d'événement. En effet, les événements n'affectent pas seulement l'élément sur lequel ils se déclenchent, ils affectent tous les éléments de la structure DOM. C'est ce qu'on appelle le transfert d'événements.
Le modèle d'événement du W3C souligne clairement le principe de la redirection d'événement. La réalisation d'un événement peut être divisée en 3 étapes.
Comme le montre la figure : Mode de transfert d'événement standard
(1) Dans la phase de capture d'événement (Capture), l'événement sera transmis vers le bas. le long de l'arborescence DOM, chaque nœud ancêtre du nœud cible, jusqu'au nœud cible. Par exemple, si l'utilisateur clique sur un lien hypertexte, l'événement click sera transféré du nœud de document vers l'élément html, l'élément body et l'élément p contenant le lien.
Au cours de ce processus, le navigateur détectera l'écouteur d'événement de capture pour l'événement et exécutera l'écouteur d'événement.
(2). Dans la phase cible, une fois que le navigateur a trouvé l'écouteur d'événement qui a été attribué à l'événement cible, il exécutera l'écouteur d'événement. Le nœud cible est le nœud DOM qui a déclenché l'événement. Par exemple, si l'utilisateur clique sur un lien hypertexte, ce lien est le nœud cible (dans ce cas, le nœud cible est en fait le nœud de texte dans le lien hypertexte).
(3). Dans la phase de bouillonnement, l'événement sera transmis vers le haut de l'arborescence DOM et les nœuds ancêtres de l'élément cible seront à nouveau visités un par un vers le nœud de document. à chaque étape du chemin. Les navigateurs détecteront les écouteurs d'événements qui ne capturent pas les écouteurs d'événements et les exécuteront.
Tous les événements ne passeront pas par la phase de bouillonnement.
Tous les événements passeront par la phase de capture et la phase de cible, mais certains événements sauteront la phase de bouillonnement. Par exemple, l'événement de focus qui fait perdre le focus d'entrée à l'élément et l'événement de flou qui fait perdre le focus d'entrée à l'élément ne feront pas de bulles.
Gestionnaire d'événements
Gestionnaire d'événements (également appelé gestionnaire d'événements, DOM l'appelle fonction d'écoute d'événements), la fonction appelée en réponse à un événement est appelée fonction de traitement d'événement
. Chaque événement correspond à un gestionnaire d'événement. Lorsque le programme est exécuté, la fonction ou l'instruction correspondante est affectée au gestionnaire d'événement. Lorsque l'événement se produit, le navigateur exécute la fonction ou l'instruction spécifiée, réalisant ainsi l'intégration du contenu de la page Web et de l'utilisateur. opérations. Lorsque le navigateur détecte qu'un événement se produit, il recherche si le gestionnaire d'événements correspondant à l'événement s'est vu attribuer une valeur. Si tel est le cas, il exécute le gestionnaire d'événements.
Nous pensons que la fonction qui répond à l'événement click est le gestionnaire d'événement onclick. Auparavant, les gestionnaires d'événements étaient attribués de deux manières : en JavaScript ou en HTML.
Si vous attribuez une fonction de gestionnaire d'événements en JavaScript, vous devez d'abord obtenir une référence à l'objet à traiter, puis attribuer la fonction à l'attribut de fonction de gestionnaire d'événements correspondant. Veuillez consulter un exemple simple :
1 var link=document.getElementById("mylink");2 link.onclick=function(){3 alert("I was clicked !");4 };
D'après les exemples que nous avons vus, nous avons constaté qu'il est facile d'utiliser des gestionnaires d'événements, mais le nom de la fonction du gestionnaire d'événements doit être en minuscules et l'événement ne peut être traité qu'après le L'élément est chargé. Le handle est affecté à l'élément, sinon il y aura une exception.
Pour la technologie de chargement de documents, veuillez consulter l'article « Solutions multiples pour le chargement de Window.onload ».
Si le gestionnaire d'événements est alloué en HTML, définissez simplement la fonction du gestionnaire d'événements directement via l'attribut HTML et incluez le script approprié comme valeur d'attribut, par exemple :
<a href="/" onclick="JavaScript code here">......</a>
Ceci Ce type de code JavaScript est similaire à l'attribution directe d'attributs CSS aux éléments via l'attribut de style HTML. Cela donne au code un aspect désordonné et viole le principe de séparation du code qui implémente un comportement dynamique du code qui affiche le contenu statique du document. Depuis 1998, cette manière d’écrire est devenue obsolète.
Cette technologie traditionnelle de liaison d'événements présente des avantages et des inconvénients évidents :
* Simple et pratique, écrivez le bloc de code de la fonction de traitement directement en HTML et attribuez des attributs d'événement aux éléments en JS. Il suffit d'attribuer une valeur.
* Une méthode prise en charge par les normes IE et DOM. Elle est appelée pendant le processus de bouillonnement d'événements dans les normes IE et DOM.
* Vous pouvez directement utiliser ceci pour faire référence à l'élément qui a enregistré l'événement dans le bloc fonctionnel de traitement. Cela fait référence à l'élément actuel.
* Si vous souhaitez enregistrer plusieurs auditeurs pour un élément, vous ne pouvez pas utiliser cette méthode.
Écouteur d'événements
En plus des gestionnaires d'événements simples déjà introduits auparavant, la plupart des navigateurs intègrent désormais des méthodes de gestion d'événements plus avancées, c'est-à-dire des écouteurs d'événements. La méthode de traitement n'est pas limitée. par le fait qu'un élément ne peut être lié qu'à un seul gestionnaire d'événements.
Nous savons déjà que la plus grande différence entre les gestionnaires d'événements et les écouteurs d'événements est que lors de l'utilisation de gestionnaires d'événements, un seul gestionnaire d'événements peut être connecté à la fois, mais pour les écouteurs d'événements, plusieurs gestionnaires d'événements peuvent être connectés. à la fois.
Écouteur d'événements sous IE :
IE提供的却是一种自有的,完全不同的甚至存在BUG的事件监听器,因此如果要让脚本在本浏览器中正常运行的话,就必须使用IE所支持的事件监听器。另外,Safari 浏览器中的事件监听器有时也存在一点不同。
在IE中,每个元素和window对象都有两个方法:attachEvent方法和detachEvent方法。
1 element.attachEvent("onevent",eventListener);
此方法的意思是在IE中要想给一个元素的事件附加事件处理函数,必须调用attachEvent方法才能创建一个事件监听器。attachEvent方法允许外界注册该元素多个事件监听器。
attachEvent接受两个参数。第一个参数是事件类型名,第二个参数eventListener是回调处理函数。这里得说明一下,有个经常会出错的地方,IE下利用attachEvent注册的处理函数调用时this指向不再是先前注册事件的元素,这时的this为window对象。还有一点是此方法的事件类型名称必须加上一个”on”的前缀(如onclick)。
1 element.attachEvent("onevent",eventListener);
要想移除先前元素注册的事件监听器,可以使用detachEvent方法进行删除,参数相同。
DOM标准下的事件监听器:
在支持W3C标准事件监听器的浏览器中,对每个支持事件的对象都可以使用addEventListener方法。该方法既支持注册冒泡型事件处理,又支持捕获型事件处理。所以与IE浏览器中注册元素事件监听器方式有所不同的。
1 //标准语法 2 element.addEventListener('event', eventListener, useCapture);3 //默认4 element.addEventListener('event', eventListener, false);
addEventListener方法接受三个参数。第一个参数是事件类型名,值得注意的是,这里事件类型名称与IE的不同,事件类型名是没’on’开头的;第二个参数eventListener是回调处理函数(即监听器函数);第三个参数注明该处理回调函数是在事件传递过程中的捕获阶段被调用还是冒泡阶段被调用 ,通常此参数通常会设置为false(为false时是冒泡),那么,如果将其值设置为true,那就创建一个捕捉事件监听器。
移除已注册的事件监听器调用element的removeEventListener方法即可,参数相同。
1 //标准语法 2 element.removeEventListener('event', eventListener, useCapture);3 //默认4 element.removeEventListener('event', eventListener, false);
通过addEventListener方法添加的事件处理函数,必须使用removeEventListener方法才能删除,而且要求参数与添加事件处理函数时addEventListener方法的参数完全一致(包括useCapture参数),否则将不能成功删除事件处理函数。
跨浏览器的注册与移除元素事件监听器方案
我们现在已经知道,对于支持addEventListener方法的浏览器,只要需要事件监听器脚本就都需要调用addEventListener方法;而对于不支持该方法的IE浏览器,使用事件监听器时则需要调用attachEvent方法。要确保浏览器使用正确的方法其实并不困难,只需要通过一个if-else语句来检测当前浏览器中是否存在addEventListener方法或attachEvent方法即可。
这样的方式就可以实现一个跨浏览器的注册与移除元素事件监听器方案:
1 var EventUtil = {
2 //注册
3 addHandler: function(element, type, handler){
4 if (element.addEventListener){
5 element.addEventListener(type, handler, false);
6 } else if (element.attachEvent){
7 element.attachEvent("on" + type, handler);
8 } else {
9 element["on" + type] = handler;
10 }
11 },
12 //移除注册
13 removeHandler: function(element, type, handler){
14 if (element.removeEventListener){
15 element.removeEventListener(type, handler, false);
16 } else if (element.detachEvent){
17 element.detachEvent("on" + type, handler);
18 } else {
19 element["on" + type] = null;
20 }
21 }
22 };
Référence des objets d'événement
Afin de mieux gérer les événements, vous pouvez effectuer différentes actions en fonction des propriétés spécifiques de l'événement qui s'est produit.
Comme le modèle d'événement, IE gère les objets différemment des autres navigateurs : IE utilise un objet événement global appelé event pour gérer les objets (il se trouve dans la variable globale window.event), tandis que tous les autres navigateurs La méthode recommandé par le W3C est d'utiliser le passage de paramètres indépendants contenant des objets d'événement.
Lors de l'implémentation d'une telle fonction dans les navigateurs, le problème le plus courant est d'obtenir une référence à l'événement lui-même et d'obtenir une référence à l'élément cible de l'événement.
Le code suivant résoudra ce problème pour vous :
1 var EventUtil ={
2 getEvent: function(event){
3 return event : window .event ;
4 },
5 getTarget : function(event){
6 return event.target || event.srcElement;
7 }
8 };
"Arrêter le bouillonnement d'événements" et "Bloquer le comportement par défaut du navigateur", ces deux concepts sont très importants et ils sont très utiles pour les traitements d'applications complexes.
1. Arrêter le bouillonnement d'événement
Arrêter le bouillonnement d'événement signifie arrêter la livraison ultérieure des événements bouillonnants (annuler la livraison de l'événement, pas seulement arrêter le type de bouillonnement commun aux événements standards IE et DOM, nous pouvons cessez également de prendre en charge les événements de capture de navigateur standard DOM, en utilisant la méthode topPropagation()). Par exemple, dans la transmission d'événements bouillonnants dans la figure ci-dessus, une fois que le traitement du corps a arrêté la transmission d'événements, l'écouteur d'événements du document supérieur ne recevra plus de notifications et ne sera plus traité.
2. Le comportement par défaut du blocage des événements
Le comportement par défaut de l'arrêt des événements signifie que généralement le navigateur exécutera l'action par défaut associée à l'événement après la livraison et le traitement de l'événement (le cas échéant). une chose existe (action). Par exemple, si l'attribut de type d'entrée dans le formulaire est « soumettre », le navigateur soumettra automatiquement le formulaire après la propagation de l'événement après avoir cliqué. Pour un autre exemple, une fois l'événement keydown de l'élément d'entrée survenu et traité, le navigateur ajoutera automatiquement les caractères saisis par l'utilisateur à la valeur de l'élément d'entrée par défaut.
Comment arrêter le bouillonnement d'événements :
Dans IE, définissez simplement CancelBubble de l'objet événement sur true.
1 function someHandle() {
2 window.event.cancelBubble = true;
3 >
La norme DOM peut être effectuée en appelant la méthode stopPropagation() de l'événement objet.
1 function someHandle(event) {
2 event.stopPropagation();
3 >
Par conséquent, la méthode de transmission de l'événement d'arrêt entre navigateurs est :
1 function someHandle(event) {
2 event = event || window.event;
3 if(event.stopPropagation){
4 event.stopPropagation();
5 } else {
6 event.cancelBubble = true;
7 }
8 }
La méthode de gestion pour empêcher le comportement par défaut de l'événement
est comme la différence entre le modèle d'événement et objet événement De même, le comportement par défaut des événements de blocage est différent dans IE et dans tous les autres navigateurs.
Dans IE, définissez simplement la returnValue de l'objet événement sur false.
1 function someHandle() {
2 window.event.returnValue = false;
3 >
La norme DOM peut être effectuée en appelant la méthode PreventDefault() de l'événement objet.
1 function someHandle(event) {
2 event.preventDefault();
3 >
Par conséquent, la méthode de traitement par défaut après la transmission de l'événement d'annulation entre navigateurs est :
1 function someHandle(event) {
2 event = event || window.event;
3 if(event.preventDefault){
4 event.preventDefault();
5 }else{
6 event.returnValue = false;
7 }
8 >
Fonction complète de compatibilité de gestion des événements
1 var EventUtil = {
2 addHandler: function(element, type, handler){
3 if (element.addEventListener){
4 element.addEventListener(type, handler, false);
5 } else if (element.attachEvent){
6 element.attachEvent("on" + type, handler);
7 } else {
8 element["on" + type] = handler ;
9 }
10 },
11 removeHandler: function(element, type, handler){
12 if (element.removeEventListener){
13 element.removeEventListener(type, handler, false);
14 } else if (element.detachEvent){
15 element.detachEvent("on" + type, handler);
16 } else {
17 element["on" + type] = null;
18 }
19 },
20 getEvent : function(event){
21 return event ? event : window.event;
22 },
23 getTarget: function(event){
24 return event.target || event.srcElement;
25 },
26 preventDefault: function(event){
27 if (event.preventDefault){
28 event.preventDefault();
29 } else {
30 event.returnValue = false;
31 }
32 },
33 stopPropagation : function(event){
34 if (event.stopPropagation){
35 event. stopPropagation( );
36 } else {
37 event.cancelBubble = true;
38 }
39 };
1. 捕获型应用场合
捕获型事件传递由最不精确的祖先元素一直到最精确的事件源元素,当一个系统组合键发生时,如果注册了系统全局快捷键监听器,该事件就先被操作系统层捕获,全局监听器就先于应用程序快捷键监听器得到通知,也就是全局的先获得控制权,它全局范围内的监听,这里的全局是相对的全局,相对于某个顶层结点与该结点所有子孙结点形成的集合范围。
例如你想作全局的点击事件监听,相对于document结点与document下所有的子结点,在某个条件下要求所有的子结点点击无效,这种情况下冒泡Il s'agit de:
1 fonction globalClickListener(événement) {
2 if(canEventPass == false) {
4 event.stopPropagation();
5 //取消浏览器事件后的默认执行
6 event.preventDefault();
7 }
8 }
这样一来,当canEventPass条件为假时,document下所有的子结点cliquez sur注册事件都不会被浏览器处理。
2. 冒泡型的应用场合
On peut dire que nous utilisons généralement le modèle d'événement bouillonnant, car IE ne prend en charge que ce modèle. Permettez-moi d'en reparler. Une utilisation appropriée de ce modèle peut améliorer les performances des scripts. Dans certains événements d'éléments fréquemment déclenchés, tels que onmousemove, onmouseover et onmouseout, s'il est clair qu'il n'est pas nécessaire de transmettre l'événement après le traitement, vous pouvez l'annuler en toute sécurité. De plus, si le traitement de l'écouteur d'événements du nœud enfant a un impact négatif sur le traitement de l'écouteur de couche parent
, la transmission ultérieure des événements vers le haut doit également être interdite dans l'écouteur du nœud enfant pour éliminer l'impact.
Enfin combinée avec le code HTML suivant pour l'analyse :
1
3
4
5
Une fois le HTML exécuté, cliquez sur la zone rouge Ceci est. le p le plus interne D'après ce qui précède, notez que qu'il s'agisse du standard DOM ou d'IE, la fonction de traitement d'écoute écrite directement en HTML est appelée lorsque l'événement est diffusé et transmis vers le haut depuis la couche la plus interne, donc
current est event_source
current apparaîtra l'un après l'autre est p2
current is p1
current is p0
current is body
Ajoutez le fragment suivant :
1 var p2 = document. .getElementById('p2');
2 EventUtil.addHandler(p2, 'click', function(event){
3 event = EventUtil.getEvent(event);
4 EventUtil.stopPropagation(event) ;
5}, false) ;
current is event_sourcecurrent is p2
Lorsque l'on clique sur la zone rouge, selon la description ci-dessus, pendant le traitement de la bulle, l'événement est arrêté après étant passé à p2, donc les éléments au dessus de p2 La notification ne peut pas être reçue, elle apparaîtra donc l'une après l'autre :
Dans un navigateur supportant le standard DOM, ajoutez le code suivant :
1 document.body.addEventListener('click', function(event) {
2 event.stopPropagation();
3}, true);
La fonction d'écoute dans le code ci-dessus est appelée lors de la livraison du type de capture, donc après avoir cliqué sur la zone rouge, bien que l'événement La source soit l'élément avec l'ID event_source, mais le type de capture est transmis à partir du niveau supérieur, la fonction d'écoute du nœud de corps est appelée en premier, et le. l'événement est annulé et transmis plus bas, donc seul le corps actuel apparaîtra.
Recommandations associées :
Explication détaillée du mécanisme de traitement des événements dans node.js
Mécanisme de traitement des événements de compatibilité du navigateur Javascript
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!