Durante el proceso de desarrollo front-end, a menudo encontramos el problema de agregar eventos a los elementos de la página. También hay muchos métodos JS para agregar eventos, incluidos directamente a la estructura de la página y algunos métodos de monitoreo de eventos JS. Dado que cada navegador tiene diferentes mecanismos para el monitoreo de eventos de burbujas de eventos, el navegador LE solo tiene burbujas de eventos y ningún mecanismo de monitoreo de eventos, y el problema de la compatibilidad de la escucha de eventos es el mayor problema:
1. Escriba el método de evento directamente en la estructura de la página
función eventFun () {//console.log(THIS); } <input type = "button" onClick = "eventFun ()" value = "botón"/> // Esto implica un problema de este alcance. EventFun también es una función global aquí. El objeto es [ventana del objeto], y esto apunta a la ventana.Para resolver este problema de alcance, puede usar el método para agregar variables de evento a la función global y pasar este objeto como un parámetro a la función dentro de la estructura de la página
<input type = "button" onClick = "eventFun2 (this)" value = "button2"/> function eventfun2 (eve) {// Aquí el objeto de eventos se pasa como un parámetro para el método global eve.name = "alex"; Window.name = "Robin"; console.log (this); // [ventana de objeto] console.log (eve); // [objeto htmlinputelement] console.log (this.name); // robin console.log (eve.name); // alexvar self = eve; console.log (this.name); // robin console.log (self.name); // alert (window.name); alerta (self.name); }2. Usar el método de asignación de valor a los atributos de eventos es un método de enlace a los eventos, pero la limitación de este método es que solo puede unir un método a los eventos. Si están vinculados múltiples enlaces, prevalecerá un método.
HtmlelementObject.OnClick = fucntion () {// Use este método para asignar el valor a los atributos de eventos, este puntero apuntará al objeto de la ventana, no al objeto de evento, por lo que este método es una referencia
// Código JS Fun1 (); fun2 (); Fun3 (); console.log (this); // window.object} function dosomThething () {// código JS} htmlelementObject.Oncclick = dosomethething; // Use este formulario de asignación de valor a los atributos del objeto de eventos, este puntero apunta a la ejecución de eventos console.log (esto); // htmlelementObject3. Propagación de eventos: burbuja y captura
El estándar de evento DOM define dos transmisiones de eventos, que son significativamente diferentes y pueden tener un impacto considerable en su aplicación. Estas dos transmisiones de eventos son captura y burbujas. Al igual que muchas tecnologías web, Netscape y Microsoft las implementaron de manera diferente antes de que se convirtieran en estándar. Netscape eligió implementar transmisiones de eventos de captura, mientras que Microsoft implementó transmisiones de eventos de burbujas. Afortunadamente, W3C decidió usar ambos métodos en combinación, y la mayoría de los navegadores nuevos siguen estos dos métodos de transmisión de eventos.
Por defecto, los eventos usan transmisiones de eventos de burbujas, y no se utilizan transmisiones de eventos de captura. Sin embargo, en Firefox y Safari, puede especificar explícitamente el uso de transmisiones de eventos de captura pasando al parámetro USECapture al registrar el evento y configurar este parámetro en verdadero.
Transmisión de eventos de burbujas
Cuando se activa un evento en un elemento DOM, por ejemplo, el usuario hace clic en el mouse en el nodo de nombre del cliente, el evento seguirá los diversos nodos principales heredados desde los cuales el nodo burbujea a través de toda la jerarquía de nodo DOM hasta que encuentre un nodo que esté conectado al procesador de tipo de evento. En este momento, el evento es el evento OnClick. El burbujeo de los eventos se puede terminar en cualquier momento durante el proceso de burbujeo. En los navegadores que cumplen con los estándares W3C, puede llamar al método stopPropagation () en el objeto de evento, y en Internet Explorer, puede establecer el atributo CancelBubble del objeto de evento a verdadero. Si el evento no se detiene, el evento burbujará a través del DOM hasta que llegue a la raíz del documento.
Flujo de eventos de captura
El procesamiento del evento comienza en la raíz del nivel DOM, en lugar del elemento objetivo que desencadena el evento, y el evento se transmite en secuencia de todos los elementos del antepasado del elemento objetivo. En este proceso, los eventos son capturados por varios elementos derivados heredados de la raíz del documento al elemento objetivo del evento. Si el oyente del evento establece el atributo USECapture en True cuando se registra, se puede asignar a cualquier elemento durante este período para manejar el evento; De lo contrario, los eventos se pasarán posteriormente al siguiente elemento en la ruta del elemento derivado hasta el elemento de destino. Después de que el evento alcanza el elemento de destino, luego burbujeará a través del nodo DOM.
Método de vinculación de eventos modernos
Para la lección anterior, el uso de la vinculación tradicional de eventos tiene muchos inconvenientes, como la incapacidad de registrar múltiples manejadores de eventos en el mismo evento de un objeto. Y los navegadores y W3C no están sin considerar esto, por lo que en los navegadores modernos, tienen sus propios métodos para vincular eventos.
W3C DOM
obj.addeventListener (Evtype, FN, Usecapture) - W3C proporciona método para agregar funciones de manejo de eventos. OBJ es el objeto para agregar eventos, evtype es el tipo de evento, sin prefijo, fn es la función del controlador de eventos, si useCapture es verdadero, la función del controlador de eventos se ejecuta en la etapa de captura, de lo contrario se ejecuta en la etapa de burbujas
obj.removeEventListener (evtype, fn, useCapture)-W3C proporciona método para eliminar las funciones de manejo de eventos
Método de Microsoft IE
obj.attachevent (evtype, fn): el método proporcionado por IE para agregar funciones de manejo de eventos. OBJ es el objeto para agregar eventos, evtype es el tipo de evento, con el prefijo, fn es la función del controlador de eventos, es decir, no admite la captura de eventos
obj.detachevent (evtype, fn,) - IE proporciona un método para eliminar la función de manejo de eventos, Evtype contiene en el prefijo
Una forma de integrar ambos
función addEvent (obj, evtype, fn, useCapture) {if (obj.addeventListener) {obj.addeventListener (evtype, fn, useCapture); } else {obj.attachevent ("en"+evtype, fn); // ie no admite captura de eventos} else {obj ["on"+evtype] = fn; // de hecho, esta situación no existirá}} función delevent (obj, evtype, fn, useCaptura) {if (obj.removeVentlistener) {) obj.removeEventListener (evtype, fn, useCapture); } else {obj.detachevent ("on"+evtype, fn); } else {obj ["on"+evtype] = null; }}Hay un problema con el método de adjunta de IE, que es que cuando se usa AttackEvent, esto apunta a la ventana, ¡no OBJ! ¡Por supuesto, hay una solución para esto!
Pero hay otro problema con el método AttachmentEvent de IE. La misma función se puede registrar con el mismo objeto y el mismo evento varias veces. Solución: ¡abandona el método de eventos de accesorio de IE! El método AttackEvent en IE no admite Capture, que no es muy diferente del registro de eventos tradicional (a excepción de los controladores de eventos múltiples vinculantes), y el método AttachmentEvent de IE tiene un problema de fuga de memoria.
AddEvent, versión moderna delevent
< xmlns = "http://www.w3.org/1999/xhtml"> <fead> <meta http-equiv = "content-type" content = "text/html; charset = utf-8"/> <title> JS Event Listening </title> <Style> table td {font: 12px; Border-Bottom: 1px Solid #efefefef;} < /style> < /head> <body> <div id = "outele" style = "padding: 10px; border: 1px sólido #b2b2b2; en segundo plano: #efefefefef;"> <input type = "button" onclick = "eventfun ()" id = "Botón" Botón = "Botón" /> <BR /> <> <Botón de entrada Tipo " onClick = "EventFun2 (this);" id = "Button2" Value = "Button2" /> <br /> <input type = "Button" id = "Button3" value = "Button3" /> <br /> <input type = "Button" id = "Button4" Value = "Button4" /> <br /> <table id = "htmleletable" Style = "borde: 1px sólido #b2b2b2; fondo: #fff;" table id = "1111"> <Td> 1111111111111111111111111111111 </td> </tr> <tr id = "222222"> <td> 2222222222222222222222222222222222222 </td> </tr> <tr id = "333333333333333333333333333333333333 </td> </tr> <tr id="44444"><td>44444444444444444444444444444444444444444444444444444444444444444444444444444444444444 4444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444 </TD> </tr> <tr id = "5555555555555555555555555555 </td> </tr> </table> </div> <script language =" javaScript "type =" text/javaScript "> función eventFun () {// 1. Escriba directamente el método JS en la estructura de página console.log (esto); // Esto implica un problema con este alcance. EventFun es una función global, el objeto es ventana y esto apunta a la alerta de la ventana (esto); } function eventfun2 (eve) {// aquí pase el objeto de eventos como parámetro al método global eve.name = "alex"; // window.name = "robin"; console.log (this); // [ventana de objeto] console.log (eve); // [objeto htmlinputelement] console.log (this.name); // robin console.log (eve.name); // alex var self = eve; console.log (this.name); // robin console.log (self.name); // alert (window.name); alerta (self.name); } función eventFun3 () {// 1. Escriba directamente el método JS en la estructura de la página console.log (esto); // Esto implica un problema de este alcance. EventFun es una función global, el objeto es ventana y esto apunta a Window Console.log (this.id); alerta (esto); alerta (esto); alerta (this.id); // var outeleobj = eventUtil. $ ("outele"); // removevent (outeleobj, "hacer clic", eventfun3); } /* var eventUtil = {}; EventUtil. $ = Function (id) {return document.getElementById (id); } EventUtil.openmes = eventFun3; EventUtil.addeventhandle = function (eventTarget, eventType, eventHandle) {// Definir el elemento de objeto, tipo de evento para la escucha de eventos, función de eventos if (eventTarget.attachevent) {eventTarget.attachevent ("en"+eventtype, eventHandle); } else if (eventTarget.AdDeventListener) {eventTarget.adDeventListener (eventType, eventHandle, false)} else {eventTarget ["on" + eventType] = null; }}; EventUtil.deleEventHandle = function (eventTarget, eventType, eventHandle) {// Definir el elemento de objeto, tipo de evento para escuchar eventos, función de eventos if (eventTarget.detachevent) {alert ("en"+eventType); alerta ("en"+eventHandle); eventTarget.detachevent ("on"+eventtype, eventHandle); } else if (eventTarget.removeEventListener) {eventTarget.RemoveEventListener (eventType, eventHandle, false)} else {eventTarget ["en" + eventType] = null; }};*/ var eventUtil = {$: function (id) {return document.getElementById (id); }, but4fun: function () {console.log (this); this.addeventhandle (); }, eventfun3: function () {console.log (this); alerta (esto); delevent (obj, evtype, fn, usecapture); }} /*** use addEventListener, adjunte para la función de escucha addEvent (obj, evtype, fn, useCapture) {if (obj.addeventListener) {obj.addeventListener (evtype, fn, useCapture); } else if (obj.attachevent) {obj.attachevent ("on"+evtype, function () {fn.call (obj);}); } else {obj ["en"+evtype] = fn; // De hecho, esta situación no existirá}} function delevent (obj, evtype, fn, useCapture) {if (obj.removeEventListener) {obj.removeeventListener (evtype, fn, useCapture); } else if (obj.detachevent) {obj.detachevent ("on"+evtype, fn); } else {obj ["on"+evtype] = null; }} function addEvent (obj, evtype, fn, useCapture) {if (obj.addeventListener) {// se da prioridad al esquema de registro de eventos W3C obj.AdDeventListener (evtype, fn, !! useCapture); } else {// Cuando AddEventListener no es compatible (es decir), ya que IE no es compatible con la captura al mismo tiempo, es mejor usar la vinculación tradicional de eventos if (! fn .__ eventId) {fn .__ eventId = addevent .__ eventHandlescounter ++;} // asignar una identificación única a cada manual de eventos if (!__ .__ .__ EventHandles) {objhandles. // _ El atributo de eventHandles se usa para guardar referencias a todos los manejadores de eventos // clasificado por tipo de evento if (! Obj .__ eventHandles [evtype]) {// en la primera vez que un evento se registra obj .__ eventHandles [evtypee] = {}; if (obj ["on"+evtype]) {// La función de manejo de eventos se ha registrado de la manera tradicional anterior (obj .__ eventHandles [evtype] [0] = obj ["on"+evtype]) .__ eventId = 0; // Agregar a los 0 bits reservados // y agregar un ID a la función de manejo de eventos original} obj ["on"+evtype] = addEvent.execEventHandles; // Cuando ocurre un evento, ExecEventHandles atraviesa la tabla obj .__ eventHandles [evtype] y ejecuta la función en it}}}} addevent .__ eventHandlesCounter = 1; // contador, 0 bit reservado con addEvent.ExeCeVeVentHandles = function (evt) {// Tranquility a través de todos los eventos de eventos y execute si (EXECUT it ((esto. verdadero;} evt = evt || Window.event; var fns = this .__ eventHandles [evt.type]; para (var i en fns) {fns [i] .call (this); }}; /* función delevent (obj, evtype, fn, useCapture) {if (obj.removeEventListener) {// Primer método W3C para eliminar la función del controlador de eventos obj.removeEventListener (evtype, fn, !! useCapture); } else {if (obj .__ eventHandles) {var fns = obj .__ eventHandles [evtype]; if (fns) {eliminar fns [fn .__ eventId];}}}}} función fixEvent (evt) {// La función fixEvent no se ejecuta por separado. ¡Debe tener un parámetro de objeto de evento, y se ejecutará solo cuando ocurra el evento! La mejor manera es integrarlo en el ExecEventHandles de la función AddEvent if (! Evt.Target) {evt.target = evt.srcelement; evt.preventDefault = FixEvent.PreventDefault; evt.stoppropagation = fixEvent.stoppropagation; if (evt.type == "mouseover") {evt.relatedTarget = evt.FromElement; } else if (evt.type == "mouseout") {evt.relatedTarget = evt.toelement; } evt.charcode = (evt.type == "KeyPress")? Evt.KeyCode: 0; evt.eventPhase = 2; // es decir, solo funciona en la etapa de burbujas evt.timestamp = (new date ()). getTime (); // siéntelo solo a la hora actual} return Evt; } fixEvent.preventDefault = function () {this.returnValue = false; // Esto aquí apunta a un determinado objeto de evento, no fixEvent}; fixEvent.stopPropagation = function () {this.cancelBubble = true; };*///console.log(EventUtil.$(("Button3"))) ;//return el atributo de objeto de la función eventUtil //eventutil.$("button3").Enclick= eventfun; // 2. Use el método de asignación de valores al atributo del evento de objeto para realizar la escucha de eventos //eventutil.$(("button3").onclick= eventfun2; // Al agregar múltiples métodos al atributo de eventos, este último es //eventututil.$("button3").Onclick= eventfun; // captura de eventos de eventos es de la inspección matriz de la capa de objeto de eventos por elyer de la capa de la ventana de la ventana de la ventana a la ventana de la ventana a la ventana de la ventana de la ventana de la ventana de la ventana de la ventana de eventos de la ventana de la ventana de la ventana de la ventana de eventos de la ventana de la ventana de la ventana de la ventana de eventos de la ventana. = function () {function getById (id) {return document.getElementById (id); }; // Escrito por Dean Edwards, 2005 // con aportes de Tino Zijdel, Matthias Miller, Diego Perini // http://dean.edwards.name/weblog/2005/10/add-event/ function addEvent (element, type, manejador) {if (element.addeventListener) {element.addeventListener (type, type, handler) {if (element.addeventListener) {element.addeventListener (type, type, handler) {if (elementDeventListener) {Element.addeventListener (type, type, Handler) {If (elementDeventListener) {Element.addeventListener (type, type, Handler). } else {// Asigna a cada controlador de eventos una identificación única if (! Handler. $$ GUID) Handler. $$ GUID = AddEvent.Guid ++; // Crear una tabla hash de tipos de eventos para el elemento if (! element.events) element.events = {}; // Cree una tabla hash de controladores de eventos para cada elemento/par de eventos var manejadores = element.events [type]; if (! Handlers) {Handlers = element.events [type] = {}; // Almacene el controlador de eventos existente (si hay uno) if (elemento ["en" + type]) {manejadores [0] = elemento ["en" + type]; }} // Almacene el controlador de eventos en los manejadores de tabla hash [Handler. $$ GUID] = Handler; // Asignar un controlador de eventos global para hacer todo el elemento de trabajo ["en" + type] = manejar; }}; // Un contador utilizado para crear IDS únicos addevent.guid = 1; function RemoLEvent (Element, Type, Handler) {if (element.removeEventListener) {element.removeEventListener (type, handler, falso); } else {// Eliminar el controlador de eventos de la tabla hash if (element.events && element.events [type]) {delete element.events [type] [manejador. $$ GUID]; }}}; función handleEvent (evento) {var returnValue = true; // Tome el objeto de evento (es decir, usa un objeto de evento global) event = Event || fixEvent (((this.OwnerDocument || this.document || this) .ParentWindow || Window) .Event); // Obtenga una referencia a la tabla hash de los manejadores de eventos var manejadores = this.events [event.type]; // Ejecutar cada controlador de eventos para (var i en los manejadores) {this. $$ handleEvent = Handlers [i]; if (this. $$ handleEvent (event) === false) {returnValue = false; }} return returnValue; }; función fixEvent (evento) {// Agregar Métodos de evento estándar W3C Event.PreventDefault = FixEvent.PreventDefault; event.stoppropagation = fixEvent.stoppropagation; evento de regreso; }; fixEvent.preventDefault = function () {this.returnValue = false; }; fixEvent.stopPropagation = function () {this.cancelBubble = true; }; función TableAdDevent () {}; return {add: addEvent, eliminar: removevent, $: getByID}} (); var outeleobj = eventUtil. $ ("outela"); //addevent.apply(EventUtil ,`outeleobj."click ", eventfun3]); //Eventutil.add(outeleobj,"click", eventfun3); var inputobj = eventUtil. $ ("Button4"); var tableele = eventUtil. $ ("htmleletable"); var tabtrele = tableele.getElementsBytagName ("tr"); EventUtil.add (Tableele, "Click", EventFun3); for (i = 0; i <tabtrele.length; i ++) {eventUtil.add (tabtrele [i], "haga clic", eventFun3); } EventUtil.remove (Tableele, "Haga clic", EventFun3); // Método de deleción de eventos eventUtil.add (tableele, "haga clic", eventfun3); // eventUtil.add (inputobj, "haga clic", eventFun3); //Eventutil.remove(outeleobj,"click", eventfun3); //Console.log(adDevent); // addEvent (inputobj, "hacer clic", eventfun3, true); // delevent (outeleobj, "hacer clic", eventfun3, falso); </script> </body> </html>PD: Aquí le proporcionamos una herramienta en línea sobre eventos JS, que resume los tipos de eventos y funciones de funciones de JS de uso común:
Una lista completa de eventos y funciones de JavaScript:
http://tools.vevb.com/table/javascript_event