Maison  >  Article  >  interface Web  >  Résumé des flux d'événements, des gestionnaires et des objets dans l'apprentissage d'événements JavaScript

Résumé des flux d'événements, des gestionnaires et des objets dans l'apprentissage d'événements JavaScript

巴扎黑
巴扎黑original
2017-08-16 11:13:121205parcourir
L'interaction entre JS et HTML se fait via des événements. Les événements sont des moments d'interaction spécifiques qui se produisent dans un document ou une fenêtre de navigateur. Vous pouvez utiliser des écouteurs (ou des gestionnaires) pour planifier des événements afin que le code approprié soit exécuté lorsque l'événement se produit. Connu sous le nom de modèle Observer dans le génie logiciel traditionnel, il prend en charge un couplage lâche entre le comportement de la page et son apparence. Cet article présentera les connaissances de base liées aux événements JS.
1. Flux d'événements
Le flux d'événements décrit l'ordre dans lequel les événements sont reçus de la page.
Bouillonnement d'événement
L'événement est initialement reçu par l'élément le plus spécifique (le nœud ayant le niveau d'imbrication le plus profond dans le document), puis se propage vers le haut vers des nœuds moins spécifiques (le document). Prenez la page HTML suivante comme exemple. Si vous cliquez sur un bouton de la page, l'événement "clic" sera propagé dans l'ordre 09e783a987af1552619f6fc9bb0a4d64, 01ef9c304b9f7adbb30fa4b02e4a20d4, < En d'autres termes, la capture d'événement signifie que l'événement se propage vers le bas le long de l'arborescence DOM depuis l'objet document jusqu'à l'élément cible réel de l'événement.
Flux d'événements DOM
Les événements spécifiés par « Événements de niveau DOM2 » comprennent trois étapes : l'étape de capture d'événement, l'étape cible et l'étape de bouillonnement d'événement. La première chose qui se produit est la capture d'événement, qui offre la possibilité d'intercepter l'événement. Ensuite, la cible réelle reçoit l'événement. La phase finale est la phase bouillonnante, où vous pouvez réagir aux événements.
En prenant le clic de bouton précédent comme exemple, dans le flux d'événements DOM, pendant la phase de capture, l'événement "click" démarre à partir du document et est transmis à l'élément body (notez que le bouton cible réel ne recevra pas l'événement pendant la phase de capture). Dans la phase cible, l'élément bouton reçoit l'événement "clic". Enfin, lors de la phase de bouillonnement, l'événement est propagé au document.
2. Gestionnaire d'événements
Un événement est une certaine action effectuée par l'utilisateur ou le navigateur lui-même, et la fonction qui répond à un événement est appelée gestionnaire d'événements ou écouteur d'événements.
Gestionnaire d'événements HTML
Le gestionnaire d'événements HTML fait ici référence au gestionnaire d'événements défini directement dans l'élément HTML via l'attribut (attribut), veuillez consulter l'exemple de code suivant. Dans ce cas, le gestionnaire d'événements créera une fonction qui encapsule la valeur d'attribut de l'élément, et cette valeur est égale à l'élément cible de l'événement. Spécifier les gestionnaires d'événements de cette manière présente plusieurs inconvénients et n'est pas recommandé.
<button onclick="alert(&#39;HaHa~&#39;)">Btn-1</button>
<button onclick="alert(&#39;event.type&#39;)">Btn-2</button>
<button onclick="handler()">Btn-3</button>
<script type="text/javascript">
 function handler() {
  alert("Haha~");
 }
</script>

Gestionnaire d'événements DOM niveau 0
La manière traditionnelle de spécifier un gestionnaire d'événements via JS consiste à attribuer une fonction à un attribut de gestionnaire d'événements, veuillez consulter l'exemple de code ci-dessous . Les gestionnaires d'événements spécifiés de cette manière s'exécutent dans la portée de l'élément, ceci faisant référence à l'élément actuel. Les gestionnaires d'événements ajoutés de cette manière seront traités pendant la phase de bouillonnement du flux d'événements. Si vous souhaitez supprimer l'événement, définissez simplement la valeur de onclick sur vide.
var btn = document.getElementById("myBtn");
btn.onclick = function() {
 console.log("this.id"); // "myBtn"
};
// 删除事件处理程序
btn.onclick = null;

Gestionnaire d'événements au niveau DOM2
"Événement au niveau DOM2" définit deux méthodes pour spécifier et supprimer les gestionnaires d'événements, addEventListener() et removeEventListener(). Ces deux méthodes sont incluses dans tous les nœuds DOM. Les deux méthodes reçoivent 3 paramètres, l'événement à traiter, la fonction de traitement et la valeur booléenne. La valeur booléenne finale signifie que le gestionnaire d'événements est appelé pendant la phase de capture lorsqu'il est vrai, et faux lorsque le gestionnaire d'événements est appelé pendant la phase de bouillonnement. Comme les méthodes de niveau DOM0, le gestionnaire d'événements ajouté ici s'exécute également dans la portée de l'élément auquel il est attaché. L'avantage de l'ajout de gestionnaires d'événements à l'aide de la méthode de niveau DOM2 est que vous pouvez ajouter plusieurs gestionnaires d'événements. Ces gestionnaires d'événements sont déclenchés dans l'ordre dans lequel ils ont été ajoutés. Voici un exemple de code :
var btn = document.getElementById("myBtn");
// 添加,触发点击事件时先输出"myBtn"再输出"HaHa~"
btn.addEventListener("click", function() {
 console.log(this.id);
}, false);
btn.addEventListener("click", function() {
 console.log("HaHa~");
}, false);

Les événements ajoutés via addEventListener() ne peuvent être supprimés que via removeEventListener(). Les paramètres transmis lors de la suppression doivent être cohérents avec les paramètres utilisés lors de l'ajout. Cela signifie également que la fonction anonyme ajoutée via addEventListener() ne peut pas être supprimée, car la fonction anonyme passée lors de l'ajout ne peut pas être transmise à removeEventListener(). Même si une fonction identique est écrite lors de la suppression, cette fonction n'est qu'une nouvelle fonction anonyme. Veuillez consulter l'exemple de code suivant :
var btn = document.getElementById("myBtn");
// 无法删除匿名函数
btn.addEventListener("click", function() {
 console.log(this.id);
}, false);
btn.removeEventListener("click", function() {
 console.log(this.id);
}, false);
  
// 正确的添加和删除方式
function handler() {
 console.log(this.id);
}
btn.addEventListener("click", handler, false);
btn.removeEventListener("click", handler, false);

Dans la plupart des cas, les gestionnaires d'événements sont ajoutés à l'étape de bouillonnement du flux d'événements, afin de maximiser la compatibilité avec différents navigateurs. Il est préférable d'ajouter des gestionnaires d'événements à la phase de capture uniquement lorsque vous devez intercepter l'événement avant qu'il n'atteigne la cible. Le conseil donné dans la programmation avancée JS est que si cela n'est pas spécifiquement nécessaire, il n'est pas recommandé d'enregistrer un gestionnaire d'événements dans la phase de capture d'événements.
Gestionnaire d'événements IE
IE实现了与DOM中类似的两个方法: attachEvent()和deleteEvent()。这两个方法接收两个参数,事件处理程序名称和事件处理程序。注意,第一个参数是事件处理程序名称而不是事件名称,也就是说在注册点击事件的处理程序时应该传入”onclick”而不是”click”,这里跟DOM的方法有些差别。另外,这两个方法注册的事件处理程序是在全局作用域中运行而不是元素作用域,this的值指向window。还有一点需要特别小心,通过attachEvent()方法也可以添加多个事件处理程序,但是它们的执行顺序却不是按照它们被添加的顺序,而是完全相反,跟DOM方法截然不同。突然觉得IE真的特别反人类~~~下面是代码示例:
var btn = document.getElementById("myBtn");
function handler1() { // ... }
function handler2() { // ... }
// 添加,触发点击事件时先执行handler2再执行handler1
btn.attachEvent("onclick", handler1);
btn.attachEvent("onclick", handler2);
// 删除
btn.deleteEvent("onclick", handler1);
btn.deleteEvent("onclick", handler2);

三、事件对象
在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含着所有与事件有关的信息,包括导致事件的元素、事件的类型以及其他与特定事件相关的信息。
DOM中的事件对象
兼容DOM的浏览器会将一个event对象传入事件处理程序中,无论指定事件处理程序时用的是DOM0还是DOM2的方法,都会传入event对象。event对象只有在事件处理程序执行期间才会存在,一旦事件处理程序执行完毕,event对象就会被销毁。下面是代码示例:
var btn = document.getElementById("myBtn");
btn.onclick = function(event) {
 console.log(event.type); // "click"
}
btn.addEventListener("click", function(event) {
 console.log(event.type);
}, false);

event对象包含与创建它的特定事件有关的属性和方法,触发的事件类型不一样,可用的属性方法也有所不同。但是所有的事件都会有下列的属性或方法:
bubbles: 布尔值,表示事件是否冒泡
cancelable: 布尔值,表示是否可以取消事件的默认行为
currentTarget: 元素,事件处理程序当前正在处理事件的那个元素
defaultPrevented: 布尔值,表示是否调用过preventDefault()方法
detail: 整数,与事件相关的细节信息
eventPhase: 整数,调用事件处理程序的阶段,1表示捕获阶段,2表示目标阶段,3表示冒泡阶段
preventDefault(): 函数,取消事件的默认行为,cancelable为true时可以调用该方法
stopImmediatePropagation(): 函数,取消事件的进一步捕获或冒泡,同时阻止任何事件处理程序被调用
stopPropagation(): 函数,取消事件的进一步捕获或冒泡,bubbles为true时可以调用这个方法
target: 元素,事件的目标
trusted: 布尔值,为true时表示事件是浏览器生成的,否则表示事件是通过JS创建的
type: 字符串,被触发的事件类型
view: 与事件关联的抽象视图,等同于发生事件的window对象
下面代码示例展示了上述部分属性的用法,也可以帮助我们进一步理解事件流。假设页面中有一个按钮”myBtn”。当点击按钮时,this和currentTarget都等于body元素,因为事件处理程序是注册在body元素上。target的值却等于按钮元素,因为它是click事件的真正目标。由于按钮上没有注册事件处理程序,结果”click”事件冒泡到了document.body那里才得到处理。
document.body.onclick = function(event) {
 console.log(event.currentTarget === document.body); // true
 console.log(this === document.body); // true
 console.log(event.target === document.getElementById("myBtn")); // true
};

再看一个例子,下面代码中,stopPropagation()方法取消了事件的进一步捕获或冒泡。当我点击按钮时,本来应该会因为事件冒泡机制触发按钮和body元素上的点击事件处理程序,输出”From Bth …”和”From Body …”。现在点击事件在按钮元素上触发之后就被阻止继续在DOM层次中的传播,因此body上的事件处理程序不会被触发。
var btn = document.getElementById("myBtn");
btn.onclick = function(event) {
 console.log("From Bth ...");
 event.stopPropagation(); // 停止事件传播
};
document.body.onclick = function() {
 console.log("From Body ...");
};

IE中的事件对象
在IE中,使用DOM0的方法添加事件处理程序时,event对象作为window对象的一个属性存在。如果是通过attachEvent()方法添加,则event对象是作为参数传入事件处理函数。下面是代码示例:
var btn = document.getElementById("myBtn");
btn.onclick = function() {
 var event = window.event;
 console.log(event.type); // "click"
};
btn.attachEvent("onclick", function(event) {
 console.log(event.type); // "click"
});

IE的event对象同样也包含与创建它的事件相关的属性和方法,这些属性和方法也会因为事件类型的不同而有所差异。但所有事件对象都会包含下列属性:
cancelBubble: 布尔值,可读可写,默认为false。将其设置为true时取消事件冒泡
returnValue: 布尔值,可读可写,默认为true。将其设置为false时取消事件的默认行为
srcElment: 元素,事件的目标元素,与DOM中的target属性相同
type: 字符串,事件类型
在IE中,事件处理程序的作用域是根据指定它的方式来确定,this的值不一定是指向事件的目标元素。因此,使用srcElement属性更具保险。请看下面代码实例,第一种方式中this的值为目标元素,而第二种方式,前面讲过这种方式的事件处理程序是在全局作用域中执行,因此this的值为window。
var btn = document.getElementById("myBtn");
btn.onclick = function() {
 console.log(window.event.srcElement === this); // true
}
btn.attachEvent("onclick", function(event) {
 console.log(event.srcElement === this); // false
});

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn