Interprétation des événements JavaScript
1. Concept de base des événements
Les événements font référence à certains moments interactifs spécifiques qui se produisent dans un document ou un navigateur, tels que l'ouverture d'une page Web et après. le navigateur est chargé L'événement load
sera déclenché Lorsque la souris survole un élément, l'événement hover
sera déclenché Lorsque la souris clique sur un élément, le <. l code>click sera déclenché, etc. La load
事件,当鼠标悬浮于某一个元素上时会触发 hover
事件,当鼠标点击某一个元素时会触发 click
事件等等。
事件处理就是当事件被触发后,浏览器响应这个事件的行为,而这个行为所对应的代码即为事件处理程序。
2. 事件操作:监听与移除监听
2.1 监听事件
浏览器会根据一些事件作出相对应的事件处理,事件处理的前提是需要监听事件,监听事件的方法主要有以下三种:
2.1.1 HTML 内联属性
即在 HTML 元素里直接填写与事件相关的属性,属性值为事件处理程序。示例如下:
<button></button>
onclick
对应着 click
事件,所以当按钮被点击后,便会执行事件处理程序,即控制台输出 You clicked me!
。
不过我们需要指出的是,这种方式将 HTML 代码与 JavaScript 代码耦合在一起,不利于代码的维护,所以应该尽量避免使用这样的方式。
2.1.2 DOM 属性绑定
通过直接设置某个 DOM 节点的属性来指定事件和事件处理程序,上代码:
const btn = document.getElementById("btn"); btn.onclick = function(e) { console.log("You clicked me!"); };
上面示例中,首先获得 btn 这个对象,通过给这个对象添加 onclick
属性的方式来监听 click
事件,这个属性值对应的就是事件处理程序。这段程序也被称作 DOM 0 级事件处理程序。
2.1.3 事件监听函数
标准的事件监听函数如下:
const btn = document.getElementById("btn"); btn.addEventListener("click", () => { console.log("You clicked me!"); }, false);
上面的示例表示先获得表示节点的 btn 对象,然后在这个对象上面添加了一个事件监听器,当监听到 click
事件发生时,则调用回调函数,即在控制台输出 You clicked me!
。addEventListener
函数包含了三个参数 false,第三个参数的含义在后面的事件触发三个阶段之后再讲解。这段程序也被称作 DOM 2 级事件处理程序。IE9+、FireFox、Safari、Chrome 和 Opera 都是支持 DOM 2 级事件处理程序的,对于 IE8 及以下版本,则用 attacEvent()
函数绑定事件。
所以我们可以写一段具有兼容性的代码:
function addEventHandler(obj, eventName, handler) { if (document.addEventListener) { obj.addEventListener(eventName, handler, false); } else if (document.attachEvent) { obj.attachEvent("on" + eventName, handler); } else { obj["on" + eventName] = handler; } }
2.2 移除事件监听
在为某个元素绑定了一个事件后,如果想接触绑定,则需要用到 removeEventListener
方法。看如下例子:
const handler = function() { // handler logic } const btn = document.getElementById("btn"); btn.addEventListener("click", handler); btn.removeEventListener("click", handler);
需要注意的是,绑定事件的回调函数不能是匿名函数,必须是一个已经被声明的函数,因为解除事件绑定时需要传递这个回调函数的引用。
同样,IE8 及以下版本也不支持上面的方法,而是用 detachEvent
La gestion des événements
est le comportement du navigateur en réponse à l'événement lorsque l'événement est déclenché, et le code correspondant à ce comportement est legestionnaire d'événements
. <p></p>2. Opérations sur les événements : surveillance et suppression de la surveillance2.1 Surveillance des événements
Le navigateur effectuera le traitement des événements correspondant en fonction de certains événements. Le principe du traitement des événements est la nécessité de surveiller les événements. : :
2.1.1 Attributs HTML en ligne
C'est-à-dire qu'il faut remplir directement les attributs liés à l'événement dans l'élément HTML, et la valeur de l'attribut est le gestionnaire d'événement. Un exemple est le suivant :
const handler = function() { // handler logic } const btn = document.getElementById("btn"); btn.attachEvent("onclick", handler); btn.detachEvent("onclick", handler);
onclick
correspond à l'événement click
, donc lorsque le bouton est cliqué, le gestionnaire d'événements sera exécuté, c'est-à-dire que les sorties de la console Vous m'avez cliqué !
. Cependant, il faut souligner que cette méthode couple le code HTML et le code JavaScript, ce qui n'est pas propice à la maintenance du code, cette méthode doit donc être évitée autant que possible.
2.1.2 Liaison d'attribut DOM
Spécifiez les événements et les gestionnaires d'événements en définissant directement les attributs d'un nœud DOM. Le code ci-dessus :
function removeEventHandler(obj, eventName, handler) { if (document.removeEventListener) { obj.removeEventListener(eventName, handler, false); } else if (document.detachEvent) { obj,detachEvent("on" + eventName, handler); } else { obj["on" + eventName] = null; } }
Dans l'exemple ci-dessus, obtenez d'abord l'objet btn, via Ajouter. l'attribut onclick
à cet objet pour écouter l'événement click
. La valeur de cet attribut correspond au gestionnaire d'événement. Ce programme est également appelé gestionnaire d'événements DOM niveau 0. 2.1.3 Fonction d'écoute d'événements
La fonction d'écoute d'événements standard est la suivante :
<div> <p>你猜,目标在这里还是<span>那里</span>。</p> </div>
L'exemple ci-dessus indique que l'objet btn représentant le nœud est d'abord obtenu, puis un écouteur d'événements est ajouté à cet objet. Lorsque l'événement click
est surveillé, la fonction de rappel est appelée, c'est-à-dire que Vous m'avez cliqué !
est affiché sur la console. La fonction addEventListener
contient trois paramètres false. La signification du troisième paramètre sera expliquée après les trois étapes de déclenchement de l'événement. Ce programme est également appelé gestionnaire d'événements DOM niveau 2. IE9+, FireFox, Safari, Chrome et Opera prennent tous en charge les gestionnaires d'événements DOM niveau 2. Pour IE8 et versions antérieures, utilisez la fonction attacEvent()
pour lier les événements.
// HTML
- Item 1
- Item 2
- Item 3
- Item 4
- Item 5
removeEventListener méthode. Regardez l'exemple suivant : 🎜<pre class="brush:php;toolbar:false">const ele = document.getElementById("ele");
ele.addEventListener("click", function() {
console.log("ele-click");
}, false);
document.addEventListener("click", function() {
console.log("document-click");
}, false);</pre>🎜Il convient de noter que la fonction de rappel de l'événement lié ne peut pas être une fonction anonyme, mais doit être une fonction déclarée, car la référence de cette fonction de rappel doit être transmise lors de la dissociation de l'événement. 🎜🎜De même, les versions IE8 et inférieures ne prennent pas en charge la méthode ci-dessus, mais utilisent plutôt <code>detachEvent
. 🎜const ele = document.getElementById("ele"); ele.addEventListener("click", function(e) { console.log("ele-click"); e.stopPropagation(); // 阻止事件冒泡 }, false); document.addEventListener("click", function(e) { console.log("document-click"); }, false);🎜De même, vous pouvez écrire une fonction de suppression d'événement compatible : 🎜
function preventBubble(e) { if (!e) { const e = window.event; } e.cancelBubble = true; if (e.stopPropagation) { e.stopPropagation(); } }🎜3. Processus de déclenchement d'événements🎜🎜Le flux d'événements décrit l'ordre dans lequel la page reçoit les événements. Le flux d'événements des navigateurs modernes (faisant référence aux navigateurs sauf IE6-IE8, y compris IE9+, FireFox, Safari, Chrome et Opera, etc.) comprend trois processus, à savoir la phase de capture, la phase cible et la phase de bouillonnement. illustre ce processus : 🎜🎜🎜🎜🎜Ces trois processus seront expliqués en détail ci-dessous. 🎜🎜3.1 Phase de capture🎜🎜Lorsque nous opérons sur un élément DOM, comme un clic de souris, un survol, etc., un événement sera transmis à l'élément DOM. Cet événement démarre à partir de la fenêtre et passe par le document, le html, le corps et. ainsi de suite. Le processus consistant à passer par les nœuds enfants jusqu'à atteindre l'élément cible, et à atteindre le nœud parent de l'élément cible depuis la fenêtre est appelé la 🎜phase de capture🎜. Notez que le nœud cible n'a pas encore été atteint à ce moment. 🎜🎜3.2 Phase cible 🎜🎜A la fin de la phase de capture, l'événement atteint le nœud parent du nœud cible, et atteint enfin le nœud cible, et déclenche l'événement sur le nœud cible. C'est la 🎜phase cible🎜. 🎜🎜Il est à noter que le nœud cible déclenché par l'événement est le nœud le plus bas. Par exemple, l'exemple suivant : 🎜
<div> <p>你猜,目标在这里还是<span>那里</span>。</p> </div>
当我们点击“那里”的时候,目标节点是<span></span>
,点击“这里”的时候,目标节点是<p></p>
,而当我们点击<p></p>
区域之外,<p></p>
区域之内时,目标节点就是<p></p>
。
3.3 冒泡阶段
当事件到达目标节点之后,就会沿着原路返回,这个过程有点类似水泡从水底浮出水面的过程,所以称这个过程为冒泡阶段。
针对这个过程,wilsonpage 做了一个 DEMO,可以非常直观地查看这个过程。
现在再看 addEventListener(eventName, handler, useCapture)
函数。第三个参数是 useCapture,代表是否在捕获阶段进行事件处理, 如果是 false, 则在冒泡阶段进行事件处理,如果是 true,在捕获阶段进行事件处理,默认是 false。这么设计的主要原因是当年微软和 netscape 之间的浏览器战争打得火热,netscape 主张捕获方式,微软主张冒泡方式,W3C 采用了折中的方式,即先捕获再冒泡。
4、事件委托
上面我们讲了事件的冒泡机制,我们可以利用这一特性来提高页面性能,事件委托便事件冒泡是最典型的应用之一。
何谓“委托”?在现实中,当我们不想做某件事时,便“委托”给他人,让他人代为完成。JavaScript 中,事件的委托表示给元素的父级或者祖级,甚至页面,由他们来绑定事件,然后利用事件冒泡的基本原理,通过事件目标对象进行检测,然后执行相关操作。看下面例子:
// HTML
- Item 1
- Item 2
- Item 3
- Item 4
- Item 5
上面的例子中,5 个列表项的点击事件均委托给了父元素 <ul id="list"></ul>
。
先看看事件委托的可行性。有人会问,当事件不是加在某个元素上的,如何在这个元素上触发事件呢?我们就是利用事件冒泡的机制,事件流到达目标元素后会向上冒泡,此时父元素接收到事件流便会执行事件执行程序。有人又会问,被委托的父元素下面如果有很多子元素,怎么知道事件流来自于哪个子元素呢?这个我们可以从事件对象中的 target
属性获得。事件对象下面会详细讲解。
我们再来看看为什么需要事件委托。
减少事件绑定。上面的例子中,也可以分别给每个列表项绑定事件,但利用事件委托的方式不仅省去了一一绑定的麻烦,也提升了网页的性能,因为每绑定一个事件便会增加内存使用。
可以动态监听绑定。上面的例子中,我们对 5 个列表项进行了事件监听,当删除一个列表项时不需要单独删除这个列表项所绑定的事件,而增加一个列表项时也不需要单独为新增项绑定事件。
看了上面的例子和解释,我们可以看出事件委托的核心就是监听一个 DOM 中更高层、更不具体的元素,等到事件冒泡到这个不具体元素时,通过 event 对象的 target 属性来获取触发事件的具体元素。
5、阻止事件冒泡
事件委托是事件冒泡的一个应用,但有时候我们并不希望事件冒泡。比如下面的例子:
const ele = document.getElementById("ele"); ele.addEventListener("click", function() { console.log("ele-click"); }, false); document.addEventListener("click", function() { console.log("document-click"); }, false);
我们本意是当点击 ele 元素区域时显示 "ele-click",点击其他区域时显示 "document-click"。但是我们发现点击 ele 元素区域时会依次显示 "ele-click" "document-click"。那是因为绑定在 ele 上的事件冒泡到了 document 上。想要解决这个问题,只需要加一行代码:
const ele = document.getElementById("ele"); ele.addEventListener("click", function(e) { console.log("ele-click"); e.stopPropagation(); // 阻止事件冒泡 }, false); document.addEventListener("click", function(e) { console.log("document-click"); }, false);
我们还能用 e.cancelBubble = true
来替代 e.stopPropagation()
。网上的说法是 cancelBubble
仅仅适用于 IE,而 stopPropagation
适用于其他浏览器。但根据我实验的结果,现代浏览器(IE9 及 以上、Chrome、FF 等)均同时支持这两种写法。为了保险起见,我们可以采用以下代码:
function preventBubble(e) { if (!e) { const e = window.event; } e.cancelBubble = true; if (e.stopPropagation) { e.stopPropagation(); } }
6、event 对象
Event 对象代表事件的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态。当一个事件被触发的时候,就会创建一个事件对象。
我们用下面的代码打印出事件对象:
<div id="list"> <li>Item 1</li> <li>Item 2</li> </div> <script> var list = document.getElementById("list"); list.addEventListener("click", function(e) { console.log(e); }); </script>
chrome 49 的运行结果如下:
下面介绍一些比较常用的属性和方法。
target、 srcElement、 currentTarget 和 relatedTarget、fromElement、 toElement
target 与 srcElement 完全相同;
target fait référence à l'élément qui a déclenché l'événement, currentTarget fait référence à l'élément auquel l'événement est lié
ratedTarget : le nœud lié au nœud cible de l'événement ; Pour les événements de survol, cette propriété est le nœud que le pointeur de la souris a quitté lors du déplacement sur le nœud cible. Pour les événements mouseout, cette propriété est le nœud dans lequel le pointeur de la souris entre en quittant la cible.
Cette propriété n'est pas utile pour d'autres types d'événements ;fromElement et toElement ne sont valables que pour les événements mouseover et mouseout.
Prenons l'exemple ci-dessus pour illustrer, lorsque l'on clique sur <li>Item 1</li>
时,target 就是 <li>Item 1</li>
元素,而 currentTarget 是 <p id="list"></p>
.
clientX/Y、 screen
clientX/Y : La position du clic est relative au coin supérieur gauche de la zone de contenu du navigateur <p></p>screenX/Y : La position du clic est relative au coin supérieur gauche de l'écran ;
- pageX/Y : La position du clic est relative à la page entière. La position du coin supérieur gauche
- <p></p> pageX/Y et clientX/Y seront généralement les mêmes, et ne seront différentes que lors d'un scroll ; la barre apparaît.
- <p></p> altKey, ctrlKey, shiftKey
- <p></p> altKey : Indique si la touche "ALT" est enfoncée lorsque l'événement est déclenché.
- <p></p> ctrlKey : Renvoie si la touche "CTRL" est enfoncée lorsque l'événement est déclenché ; . Suivant ;
- <p></p> shiftKey : Indique si la touche "SHIFT" est enfoncée lorsque l'événement est déclenché.
- Autres propriétés
- <p></p> type : Renvoie le nom de l'événement représenté par l'objet Event actuel ;
bubbles : Renvoie une valeur booléenne, indiquant si l'événement est un événement de type bulle ;
cancelable : Renvoie une valeur booléenne, indiquant si l'événement peut avoir une action par défaut annulable ;
eventPhase : Renvoie l'action actuelle ; étape de propagation de l'événement, il existe trois valeurs : Event.CAPTURING_PHASE, Event.AT_TARGET, Event.BUBBLING_PHASE, les valeurs correspondantes sont 1, 2 et 3, qui représentent respectivement la phase de capture, la répartition normale des événements et la phase de bouillonnement ;
- path : le nœud passé par la phase de bouillonnement ; <p></p>
- Method<p></p>
- preventDefault() : avertit le navigateur de ne pas effectuer l'action par défaut associée à l'événement ; <p></p>
- stopPropagation() : empêche le bouillonnement ; <p></p>
- Etude recommandée : "<p></p>Tutoriel de base js