Maison > Article > interface Web > Explication détaillée de l'écriture d'événements personnalisés dans les connaissances JavaScript_Basic
Nous pouvons personnaliser les événements pour obtenir un développement plus flexible. Les événements peuvent être un outil très puissant s'ils sont utilisés correctement. Le développement basé sur les événements présente de nombreux avantages (décrits plus loin).
Les fonctions liées aux événements personnalisés incluent Event, CustomEvent et dispatchEvent.
Pour personnaliser directement les événements, utilisez le constructeur Event :
var event = new Event('build'); // Listen for the event. elem.addEventListener('build', function (e) { ... }, false); // Dispatch the event. elem.dispatchEvent(event);
CustomEvent peut créer un événement plus personnalisé et peut également joindre certaines données. L'utilisation spécifique est la suivante :
var myEvent = new CustomEvent(eventname, options);
où les options peuvent être :
{ detail: { ... }, bubbles: true, cancelable: false }
Detail peut stocker certaines informations d'initialisation et peut être appelé lorsqu'il est déclenché. D'autres propriétés définissent si l'événement a des fonctions de bouillonnement, etc.
Les événements intégrés seront déclenchés par le navigateur en fonction de certaines opérations, tandis que les événements personnalisés doivent être déclenchés manuellement. La fonction dispatchEvent permet de déclencher un événement :
element.dispatchEvent(customEvent);
Le code ci-dessus indique que l'événement customEvent est déclenché sur l'élément. Utilisés ensemble :
// add an appropriate event listener obj.addEventListener("cat", function(e) { process(e.detail) }); // create and dispatch the event var event = new CustomEvent("cat", {"detail":{"hazcheeseburger":true}}); obj.dispatchEvent(event);
L'utilisation d'événements personnalisés nécessite de prêter attention aux problèmes de compatibilité, mais utiliser jQuery est beaucoup plus simple :
// 绑定自定义事件 $(element).on('myCustomEvent', function(){}); // 触发事件 $(element).trigger('myCustomEvent'); 此外,你还可以在触发自定义事件时传递更多参数信息: $( "p" ).on( "myCustomEvent", function( event, myName ) { $( this ).text( myName + ", hi there!" ); }); $( "button" ).click(function () { $( "p" ).trigger( "myCustomEvent", [ "John" ] ); });
Les événements personnalisés JavaScript sont des événements personnalisés qui diffèrent des événements standards tels que cliquer, soumettre, etc. Avant de décrire les avantages des événements personnalisés, regardons un exemple d'événement personnalisé :
<div id="testBox"></div> // 创建事件 var evt = document.createEvent('Event'); // 定义事件类型 evt.initEvent('customEvent', true, true); // 在元素上监听事件 var obj = document.getElementById('testBox'); obj.addEventListener('customEvent', function(){ console.log('customEvent 事件触发了'); }, false);
Pour des effets spécifiques, vous pouvez voir la démo. Entrez obj.dispatchEvent(evt) dans la console. Vous pouvez voir que « l'événement customEvent est déclenché » est affiché dans la console, indiquant que l'événement personnalisé est déclenché avec succès.
Dans ce processus, la méthode createEvent crée un événement vide, puis utilise la méthode initEvent pour définir le type d'événement comme événement personnalisé convenu, puis surveille l'élément correspondant, puis utilise dispatchEvent pour déclencher l'événement.
Oui, le mécanisme des événements personnalisés est le même que celui des événements ordinaires : écoutez l'événement, écrivez l'opération de rappel et exécutez le rappel après le déclenchement de l'événement. Mais la différence est que nous contrôlons entièrement les événements personnalisés lorsqu’ils sont déclenchés, ce qui signifie qu’une sorte de découplage JavaScript est réalisé. Nous pouvons contrôler de manière flexible plusieurs opérations liées mais logiquement complexes à l'aide du mécanisme d'événements personnalisé.
Bien sûr, vous avez peut-être deviné que le code ci-dessus ne prend pas effet dans les versions inférieures d'IE. En fait, createEvent() n'est pas pris en charge dans IE8 et les versions inférieures d'IE, mais il existe la méthode privée fireEvent() d'IE. , mais malheureusement, fireEvent ne prend en charge que le déclenchement d'événements standard. Par conséquent, nous ne pouvons utiliser qu’une méthode spéciale et simple pour déclencher des événements personnalisés.
// type 为自定义事件,如 type = 'customEvent',callback 为开发者实际定义的回调函数 obj[type] = 0; obj[type]++; obj.attachEvent('onpropertychange', function(event){ if( event.propertyName == type ){ callback.call(obj); } });
Le principe de cette méthode est en fait d'ajouter un attribut personnalisé au DOM et en même temps d'écouter l'événement propertychange de l'élément Lorsque la valeur d'une propriété du DOM change, le rappel propertychange sera déclenché, puis l'événement sera jugé dans le rappel. Si l'attribut modifié est notre attribut personnalisé, si tel est le cas, le rappel réellement défini par le développeur sera exécuté. Cela simule le mécanisme des événements personnalisés.
Afin de faire coopérer le mécanisme d'événements personnalisés avec le déclenchement de surveillance et de simulation d'événements standard, un mécanisme d'événements complet est présenté ici. Ce mécanisme prend en charge les opérations de surveillance, de suppression de surveillance et de déclenchement de simulation d'événements standard et d'événements personnalisés. Il est à noter que afin de rendre la logique du code plus claire, il est convenu que les événements personnalisés soient préfixés par 'custom' (par exemple : customTest, customAlert).
/** * @description 包含事件监听、移除和模拟事件触发的事件机制,支持链式调用 * */ (function( window, undefined ){ var Ev = window.Ev = window.$ = function(element){ return new Ev.fn.init(element); }; // Ev 对象构建 Ev.fn = Ev.prototype = { init: function(element){ this.element = (element && element.nodeType == 1)? element: document; }, /** * 添加事件监听 * * @param {String} type 监听的事件类型 * @param {Function} callback 回调函数 */ add: function(type, callback){ var _that = this; if(_that.element.addEventListener){ /** * @supported For Modern Browers and IE9+ */ _that.element.addEventListener(type, callback, false); } else if(_that.element.attachEvent){ /** * @supported For IE5+ */ // 自定义事件处理 if( type.indexOf('custom') != -1 ){ if( isNaN( _that.element[type] ) ){ _that.element[type] = 0; } var fnEv = function(event){ event = event ? event : window.event if( event.propertyName == type ){ callback.call(_that.element); } }; _that.element.attachEvent('onpropertychange', fnEv); // 在元素上存储绑定的 propertychange 的回调,方便移除事件绑定 if( !_that.element['callback' + callback] ){ _that.element['callback' + callback] = fnEv; } // 标准事件处理 } else { _that.element.attachEvent('on' + type, callback); } } else { /** * @supported For Others */ _that.element['on' + type] = callback; } return _that; }, /** * 移除事件监听 * * @param {String} type 监听的事件类型 * @param {Function} callback 回调函数 */ remove: function(type, callback){ var _that = this; if(_that.element.removeEventListener){ /** * @supported For Modern Browers and IE9+ */ _that.element.removeEventListener(type, callback, false); } else if(_that.element.detachEvent){ /** * @supported For IE5+ */ // 自定义事件处理 if( type.indexOf('custom') != -1 ){ // 移除对相应的自定义属性的监听 _that.element.detachEvent('onpropertychange', _that.element['callback' + callback]); // 删除储存在 DOM 上的自定义事件的回调 _that.element['callback' + callback] = null; // 标准事件的处理 } else { _that.element.detachEvent('on' + type, callback); } } else { /** * @supported For Others */ _that.element['on' + type] = null; } return _that; }, /** * 模拟触发事件 * @param {String} type 模拟触发事件的事件类型 * @return {Object} 返回当前的 Kjs 对象 */ trigger: function(type){ var _that = this; try { // 现代浏览器 if(_that.element.dispatchEvent){ // 创建事件 var evt = document.createEvent('Event'); // 定义事件的类型 evt.initEvent(type, true, true); // 触发事件 _that.element.dispatchEvent(evt); // IE } else if(_that.element.fireEvent){ if( type.indexOf('custom') != -1 ){ _that.element[type]++; } else { _that.element.fireEvent('on' + type); } } } catch(e){ }; return _that; } } Ev.fn.init.prototype = Ev.fn; })( window ); 测试用例1(自定义事件测试) // 测试用例1(自定义事件测试) // 引入事件机制 // ... // 捕捉 DOM var testBox = document.getElementById('testbox'); // 回调函数1 function triggerEvent(){ console.log('触发了一次自定义事件 customConsole'); } // 回调函数2 function triggerAgain(){ console.log('再一次触发了自定义事件 customConsole'); } // 封装 testBox = $(testBox); // 同时绑定两个回调函数,支持链式调用 testBox.add('customConsole', triggerEvent).add('customConsole', triggerAgain);
Le code complet est dans Démo.
Après avoir ouvert la démo, appelez testBox.trigger('customConsole') dans la console pour déclencher l'événement personnalisé par vous-même. Vous pouvez voir que la console affiche deux invites. Entrez ensuite testBox.remove('customConsole', triggerAgain) pour supprimer la paire. Pour ce dernier écouteur, utilisez testBox.trigger('customConsole') pour déclencher un événement personnalisé. Vous pouvez voir que la console génère uniquement une invite, c'est-à-dire que le dernier écouteur est supprimé avec succès. toutes les fonctions du mécanisme événementiel fonctionnent normalement.