Si vous utilisez l'écriture moins, faites plus de framework comme jQuery, vous serez inévitablement tenté par JS natif.
Xiaocai ne veut en fait pas écrire ce blog, il semble être très rudimentaire, mais en voyant qu'elle ne peut même pas expliquer la contrainte et le démantèlement des événements natifs JS sur Internet, elle a décidé de faire des sciences populaires.
Tout d'abord, Xiaocai ne sait pas grand-chose, partagez simplement mes idées avec vous.
Modèle d'événement DOM0
Les modèles d'événements évoluent constamment et les premiers modèles d'événements sont appelés le niveau DOM0.
Modèle d'événement DOM0, pris en charge par tous les navigateurs.
L'enregistrement du nom d'événement directement sur l'objet DOM est la méthode d'écriture DOM0, telle que:
La copie de code est la suivante:
document.getElementById ("test"). onClick = function (e) {};
Cela signifie enregistrer un événement OnClick. Bien sûr, il a la même signification que cette écriture:
La copie de code est la suivante:
document.getElementById ("test") ["OnMousMove"] = fonction (e) {};
Ce n'est rien, ce n'est que deux façons d'accéder aux propriétés de l'objet JS. La forme de [] consiste principalement à résoudre le problème que le nom d'attribut n'est pas un identifiant légal. Par exemple, Object.123 doit signaler une erreur, mais l'objet ["123"] évite ce problème. Dans le même temps, l'écriture de [] écrit également JS vivant, en utilisant des chaînes pour représenter le nom d'attribut, qui peut lier dynamiquement les événements à l'exécution.
Retour au point, lorsque l'événement est déclenché, un paramètre E sera passé par défaut pour représenter l'objet de l'événement. Grâce à E, nous pouvons obtenir beaucoup d'informations utiles, telles que les coordonnées du clic, l'élément DOM qui a spécifiquement déclenché l'événement, etc.
Sur la base des événements DOM0, pour le même nœud Dom, un seul peut être enregistré, et le même événement enregistré plus tard remplacera les précédents enregistrés. Par exemple:
La copie de code est la suivante:
var btn = document.getElementById ("test");
btn.onMouseMove = fonction (e) {
alert ("ok");
};
btn ["onMouseMove"] = fonction (e) {
alert ("ok1");
};
Le résultat sortira OK1.
Parlons-en ensuite. Lorsqu'un événement est déclenché, cela se réfère à quel objet DOM L'événement est déclenché. Par exemple:
La copie de code est la suivante:
var btn = document.getElementById ("test");
btn.onMouseMove = fonction (e) {
alerte (this.id);
};
Le test de sortie du résultat. Étant donné que l'événement est enregistré sur le nœud DOM avec le test ID, lorsque l'événement est déclenché, cela représente bien sûr ce nœud DOM. On peut comprendre que l'événement est appelé par ce nœud DOM.
Par conséquent, il est assez simple d'annuler l'événement. Il vous suffit d'enregistrer à nouveau l'événement et de définir la valeur sur NULL, par exemple:
La copie de code est la suivante:
var btn = document.getElementById ("test");
btn.onclick = fonction (e) {
alert ("ok");
};
btn.onclick = null;
Le principe est que le dernier événement enregistré doit écraser le précédent. Définissez le dernier événement enregistré sur NULL, qui déliera l'événement.
La question n'est pas encore terminée et le modèle d'événement DOM0 implique également des événements écrits directement dans le HTML. Par exemple:
La copie de code est la suivante:
<div id = "test" onclick = "exec ();" > </div>
Les événements enregistrés de cette manière suivent également le principe de la couverture, et un seul peut être enregistré et le dernier prendra effet.
La différence est que l'événement enregistré de cette manière est équivalent à appeler une fonction dynamiquement (quelque peu EVAL signifie), donc l'objet de l'événement ne sera pas passé. En même temps, cela pointe vers la fenêtre, et n'est plus l'objet DOM qui déclenche l'événement.
Modèle d'événement DOM2
Par rapport à DOM0, Shouca ne comprend que les deux points suivants:
・ DOM2 prend en charge l'enregistrement de plusieurs mêmes événements avec le même élément DOM.
・ Dom2 a ajouté le concept de capture et de bouillonnement.
Les événements DOM2 sont gérés par AdVEventListener et RemoveEventListener, bien sûr, c'est la norme.
Cependant, IE8 et les navigateurs suivants ont créé Corresponding attachEvent et Detachevent. Étant donné que Xiaocai est un peu involontaire, cet article n'en discutera pas.
AddeventListener est bien sûr l'événement d'inscription. Il a trois paramètres, à savoir: "Nom de l'événement", "rappel d'événements" et "capture / bulle". Par exemple:
La copie de code est la suivante:
var btn = document.getElementById ("test");
btn.addeventListener ("cliquez", fonction (e) {
alert ("ok");
}, FAUX);
Inutile de dire que le nom de l'événement n'est pas trop. Comparé à DOM0, le précédent est juste enlevé.
Les rappels d'événements sont également faciles à comprendre. Vous devez vous informer si l'événement est déclenché! Lorsque vous rappelez, comme DOM0, un paramètre d'événement sera passé par défaut. Dans le même temps, cela fait référence au nœud DOM qui déclenche l'événement.
Le dernier paramètre est le type booléen, True représente l'événement de capture, et False représente l'événement bulle. En fait, c'est facile à comprendre. Faisons d'abord un diagramme:
Cela signifie que si un élément déclenche un événement, la première chose qui est notifiée est la fenêtre, puis le document, et va en séquence jusqu'à l'élément (élément cible) qui déclenche réellement l'événement. Ce processus est la capture. Ensuite, l'événement bouillonnera à partir de l'élément cible, puis sortira en séquence jusqu'à l'objet de fenêtre. Ce processus est bulle.
Pourquoi concevoir de cette façon? Cela semble être dû à ses origines historiques profondes, donc Xiaocai n'en sait pas grand-chose, donc elle ne parlera pas de bêtises.
De cela, nous pouvons voir que l'événement de capture est déclenché avant l'événement de bulle.
Supposons qu'il existe une telle structure HTML:
La copie de code est la suivante:
<div id = "test">
<div id = "Testinner"> </div>
</div>
Ensuite, nous enregistrons deux événements de clic sur la div externe, à savoir l'événement de capture et l'événement bouillonnant, le code est le suivant:
La copie de code est la suivante:
var btn = document.getElementById ("test");
// Catch des événements
btn.addeventListener ("cliquez", fonction (e) {
alert ("ok1");
}, vrai);
// événement bouillonnant
btn.addeventListener ("cliquez", fonction (e) {
alert ("ok");
}, FAUX);
Enfin, cliquez sur le div intérieur, apparaissez d'abord OK1, puis apparaissez OK. Combiné avec le schéma ci-dessus, la div externe est équivalente au corps de la figure, et la div intérieure est équivalente à la div inférieure sur la figure, prouvant que l'événement de capture est exécuté en premier, puis l'événement de bulle est exécuté.
Pourquoi mettre l'accent sur le clic sur la div intérieure? Parce que l'élément DOM qui déclenche vraiment l'événement doit provenir de la couche intérieure, et l'élément DOM de couche externe a la possibilité de simuler et de capturer des événements et des événements bulles, qui peuvent être vus à partir du diagramme schématique.
Et si vous enregistrez l'événement Capture et l'événement Bubbling sur l'élément DOM qui déclenche réellement l'événement?
La structure HTML est la même que ci-dessus, et le code JS est le suivant:
La copie de code est la suivante:
var btninner = document.getElementById ("Testinner");
// événement bouillonnant
btninner.addeventListener ("cliquez", fonction (e) {
alert ("ok");
}, FAUX);
// Catch des événements
btninner.addeventListener ("cliquez", fonction (e) {
alert ("ok1");
}, vrai);
Bien sûr, cliquez sur le div intérieur, et le résultat est qu'OK apparaît d'abord, puis OK1. En théorie, l'événement de capture doit être déclenché en premier, c'est-à-dire que OK1 apparaît en premier, mais voici spécial, car nous enregistrons un événement sur l'élément DOM qui déclenche réellement l'événement, ce qui équivaut à s'inscrire sur la div sur la figure. D'après la figure, nous pouvons voir que l'élément DOM qui déclenche réellement l'événement est le point final de l'événement de capture et le point de départ de l'événement de bulle, il n'y a donc pas de distinction entre les événements ici. Le celui qui enregistre d'abord, exécute le premier. Dans cet exemple, l'événement de bulle est enregistré en premier, il est donc exécuté en premier.
Ce principe s'applique à plusieurs événements du même type. Par exemple, si 3 événements de bulle sont enregistrés immédiatement, l'ordre d'exécution sera dans l'ordre d'enregistrement, le premier enregistrement et la première exécution. Par exemple:
La copie de code est la suivante:
var btninner = document.getElementById ("Testinner");
btninner.addeventListener ("cliquez", fonction (e) {
alert ("ok");
}, FAUX);
btninner.addeventListener ("cliquez", fonction (e) {
alert ("ok1");
}, FAUX);
btninner.addeventListener ("cliquez", fonction (e) {
alert ("ok2");
}, FAUX);
Le résultat est bien sûr OK, OK1 et OK2 Pop-ups tour à tour.
Afin de comprendre davantage le modèle d'événement, il existe un autre scénario. Si la div externe et la div intérieure enregistrent l'événement de capture en même temps, lors de la cliquetis sur la div intérieure, l'événement externe DIV doit être déclenché en premier. Le code est le suivant:
La copie de code est la suivante:
var btn = document.getElementById ("test");
var btninner = document.getElementById ("Testinner");
btninner.addeventListener ("cliquez", fonction (e) {
alert ("ok");
}, vrai);
btn.addeventListener ("cliquez", fonction (e) {
alert ("ok1");
}, vrai);
Le résultat est que OK1 apparaît en premier.
Si la div externe et la div intérieure sont des événements de bulle enregistrés, lors du clic sur le div intérieur, l'événement Inner Div doit être exécuté en premier, et le principe est le même.
Les lecteurs prudents constateront que pour le cas de Div Nesting, si vous cliquez sur la div intérieure, la div externe déclenchera également un événement, ce qui semble être un problème!
Le clic est clairement le div intérieur, mais l'événement externe Div est également déclenché, ce qui est en effet un problème.
En fait, lorsque l'événement est déclenché, un objet d'événement sera passé par défaut. Comme mentionné précédemment, il existe une méthode sur cet objet d'événement: stopPropagation. Grâce à cette méthode, les bulles peuvent être empêchées, afin que la div externe ne reçoive pas l'événement. Le code est le suivant:
La copie de code est la suivante:
var btn = document.getElementById ("test");
var btninner = document.getElementById ("Testinner");
btn.addeventListener ("cliquez", fonction (e) {
alert ("ok1");
}, FAUX);
btninner.addeventListener ("cliquez", fonction (e) {
// Arrête les bulles
e.stoppropagation ();
alert ("ok");
}, FAUX);
Enfin, je dois parler de la façon de résoudre l'incident. Syntaxe Unévante: btn.RemoveEventListener ("Nom d'événement", "Rappel d'événements", "capture / bubble");
Ceci est le même que les paramètres de l'événement de liaison, comme décrit en détail:
・ Le nom de l'événement signifie annuler l'événement.
・ L'appel de l'événement est une fonction, qui doit être la même que la fonction qui enregistre l'événement.
・ Type d'événement, valeur booléenne, cela doit être cohérent avec le type lorsque l'événement est enregistré.
En d'autres termes, le nom, le rappel et le type décident ensemble de l'événement à annuler, est indispensable. Par exemple:
La copie de code est la suivante:
var btn = document.getElementById ("test");
// stockant le rappel dans une variable
var fn = fonction (e) {
alert ("ok");
};
//Obligatoire
btn.addeventListener ("click", fn, false);
//Suppression
btn.reMoveEventListener ("click", fn, false);
Pour que l'événement enregistré soit annulé, la fonction de rappel doit être enregistrée, sinon elle ne peut pas être annulée.
DOM0 mixte et DOM2
Les choses sont déjà très désordonnées, et c'est une utilisation mixte, ce qui fait vivre les gens. . .
N'ayez pas peur, ce n'est pas un problème de l'utiliser de manière mitigée. Le modèle DOM0 et le modèle DOM2 suivent chacun leurs propres règles et ne se affectent pas mutuellement.
Dans l'ensemble, il n'y a rien d'autre s'il est enregistré en premier et exécuté en premier.
post-scriptum
À ce stade, l'événement natif JS a été presque terminé. Xiaocai ne le sait que. Les lecteurs sont invités à ajouter d'autres points de connaissance.
Dans les applications réelles, les vrais experts n'enregistreront pas stupidement autant d'événements. D'une manière générale, vous n'avez qu'à enregistrer un événement sur l'élément DOM le plus extérieur, puis à utiliser le mécanisme de capture et de bulle pour trouver l'élément DOM qui déclenche réellement l'événement, et enfin appeler le rappel en fonction des informations fournies par l'élément DOM qui déclenche l'événement.
En d'autres termes, les experts géreront eux-mêmes les événements sans compter sur les navigateurs pour les gérer, ce qui peut améliorer l'efficacité et assurer la compatibilité. N'est-ce pas ce que fait jQuery?
Ok, le tutoriel se termine ici, j'espère que ce sera utile aux lecteurs!