Heim > Artikel > Web-Frontend > Detaillierte Erklärung zum Schreiben benutzerdefinierter Ereignisse in JavaScript_Grundkenntnisse
Wir können Ereignisse anpassen, um eine flexiblere Entwicklung zu erreichen. Ereignisse können ein sehr leistungsfähiges Werkzeug sein, wenn sie richtig eingesetzt werden. Die ereignisbasierte Entwicklung bietet viele Vorteile (später beschrieben).
Zu den Funktionen im Zusammenhang mit benutzerdefinierten Ereignissen gehören „Event“, „CustomEvent“ und „dispatchEvent“.
Um Ereignisse direkt anzupassen, verwenden Sie den Ereigniskonstruktor:
var event = new Event('build'); // Listen for the event. elem.addEventListener('build', function (e) { ... }, false); // Dispatch the event. elem.dispatchEvent(event);
CustomEvent kann ein stärker angepasstes Ereignis erstellen und auch einige Daten anhängen. Die spezifische Verwendung ist wie folgt:
var myEvent = new CustomEvent(eventname, options);
wobei Optionen sein können:
{ detail: { ... }, bubbles: true, cancelable: false }
Detail kann einige Initialisierungsinformationen speichern und bei Auslösung aufgerufen werden. Andere Eigenschaften legen fest, ob das Ereignis über Bubbling-Funktionen usw. verfügt.
Eingebaute Ereignisse werden vom Browser basierend auf bestimmten Vorgängen ausgelöst, während benutzerdefinierte Ereignisse manuell ausgelöst werden müssen. Die Funktion „dispatchEvent“ wird verwendet, um ein Ereignis auszulösen:
element.dispatchEvent(customEvent);
Der obige Code zeigt an, dass das Ereignis „customEvent“ für das Element ausgelöst wird. Zusammen verwendet:
// 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);
Die Verwendung benutzerdefinierter Ereignisse erfordert die Beachtung von Kompatibilitätsproblemen, die Verwendung von jQuery ist jedoch viel einfacher:
// 绑定自定义事件 $(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" ] ); });
Benutzerdefinierte JavaScript-Ereignisse sind benutzerdefinierte Ereignisse, die sich von Standardereignissen wie Klicken, Senden usw. unterscheiden. Bevor wir die Vorteile benutzerdefinierter Ereignisse beschreiben, schauen wir uns ein Beispiel für ein benutzerdefiniertes Ereignis an:
<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);
Für bestimmte Effekte können Sie die Demo anzeigen. Geben Sie obj.dispatchEvent(evt) in die Konsole ein. In der Konsole wird angezeigt, dass das benutzerdefinierte Ereignis erfolgreich ausgelöst wurde.
In diesem Prozess erstellt die Methode „createEvent“ ein leeres Ereignisereignis, verwendet dann die Methode „initEvent“, um den Ereignistyp als vereinbartes benutzerdefiniertes Ereignis zu definieren, überwacht dann das entsprechende Element und verwendet dann „dispatchEvent“, um das Ereignis auszulösen.
Ja, der Mechanismus benutzerdefinierter Ereignisse ist der gleiche wie bei gewöhnlichen Ereignissen: Hören Sie sich das Ereignis an, schreiben Sie die Rückrufoperation und führen Sie den Rückruf aus, nachdem das Ereignis ausgelöst wurde. Der Unterschied besteht jedoch darin, dass benutzerdefinierte Ereignisse bei ihrer Auslösung vollständig von uns kontrolliert werden, wodurch eine Art JavaScript-Entkopplung erreicht wird. Mithilfe des benutzerdefinierten Ereignismechanismus können wir mehrere zusammenhängende, aber logisch komplexe Vorgänge flexibel steuern.
Natürlich haben Sie vielleicht vermutet, dass der obige Code in niedrigeren Versionen des IE nicht wirksam wird. Tatsächlich wird createEvent() in IE8 und niedrigeren Versionen des IE nicht unterstützt, aber es gibt die private fireEvent()-Methode des IE . , aber leider unterstützt fireEvent nur das Auslösen von Standardereignissen. Daher können wir zum Auslösen benutzerdefinierter Ereignisse nur eine spezielle und einfache Methode verwenden.
// type 为自定义事件,如 type = 'customEvent',callback 为开发者实际定义的回调函数 obj[type] = 0; obj[type]++; obj.attachEvent('onpropertychange', function(event){ if( event.propertyName == type ){ callback.call(obj); } });
Das Prinzip dieser Methode besteht darin, dem DOM ein benutzerdefiniertes Attribut hinzuzufügen und gleichzeitig das PropertyChange-Ereignis des Elements abzuhören. Wenn sich der Wert einer Eigenschaft des DOM ändert, wird der PropertyChange-Rückruf ausgelöst. Anschließend wird im Rückruf beurteilt, ob das geänderte Attribut unser benutzerdefiniertes Attribut ist. Wenn ja, wird der vom Entwickler tatsächlich definierte Rückruf ausgeführt. Dadurch wird der Mechanismus benutzerdefinierter Ereignisse simuliert.
Damit der benutzerdefinierte Ereignismechanismus mit der Überwachung und Simulationsauslösung von Standardereignissen zusammenarbeitet, wird hier ein vollständiger Ereignismechanismus bereitgestellt. Dieser Mechanismus unterstützt die Überwachung, Entfernung von Überwachungs- und Simulationsauslösungsvorgängen von Standardereignissen und benutzerdefinierten Ereignissen. Es ist zu beachten, dass zur Verdeutlichung der Logik des Codes vereinbart wird, dass benutzerdefinierten Ereignissen das Präfix „custom“ vorangestellt wird (z. B.: 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);
Der vollständige Code befindet sich in der Demo.
Nachdem Sie die Demo geöffnet haben, rufen Sie testBox.trigger('customConsole') in der Konsole auf, um das benutzerdefinierte Ereignis selbst auszulösen. Sie können sehen, dass die Konsole zwei Eingabeaufforderungen ausgibt. Geben Sie dann testBox.remove('customConsole', triggerAgain) ein. Um das Paar zu entfernen, verwenden Sie testBox.trigger('customConsole'), um ein benutzerdefiniertes Ereignis auszulösen. Sie können sehen, dass die Konsole nur eine Eingabeaufforderung ausgibt, d. h. der letzte Listener wurde erfolgreich entfernt. Alle Funktionen des Ereignismechanismus funktionieren normal.