fondo
Hay varios problemas menores cuando los eventos vinculantes usando addEventListener () o adjectEvent () en JavaScript:
1. La función anónima agregada usando addEventListener () o adjunta () no se puede eliminar.
La copia del código es la siguiente: var obtn = document.getElementById ('btn');
OBTN.AdDeventListener ('Click', function () {
alerta (se hace clic en 'el botón')
},FALSO)
OBTN.REOMVEEVENTLISTENER ('Click', function () {
alerta (se hace clic en 'el botón')
},FALSO)
// El evento en OBTN no se puede eliminar porque se pasa una función anónima en
2. En IE6-II8, el problema de ejecución de orden inverso de múltiples eventos se limita usando adjectEvent ().
La copia del código es la siguiente:
var obtn = document.getElementById ('btn');
OBTN.ATTACHEVENT ('OnClick', function () {
alerta (1)
})
OBTN.ATTACHEVENT ('OnClick', function () {
alerta (2)
})
OBTN.ATTACHEVENT ('OnClick', function () {
Alerta (3)
})
// Orden de ejecución EIE9+ 1, 2, 3
// órdenes de ejecución bajo IE6-II8 3, 2, 1
Resolver el problema
Quiero escribir un módulo de vinculación de eventos cruzados para que pueda reutilizarse más tarde, y al mismo tiempo quiero resolver el problema de apelación. JQuery utiliza colas de eventos y mecanismos de almacenamiento en caché de datos para resolver este problema. Miré el código fuente relevante. Fue realmente complicado. Probé algunos métodos yo mismo y apenas los implementé. El código está publicado en objetos orientado, y no quiero que la gente lo vea complicada, por lo que lo cambio en funciones para organizarlo.
La copia del código es la siguiente:
/*Interfaz de eventos vinculantes
*
*@param {dom-dom} y {type-string} y {fn-function} parámetros opcionales {fnname-string}
*@Ejecutar Crear una cola de eventos y agréguela a las propiedades del objeto DOM.
Agregar controlador de eventos (función) a la cola de eventos
Se puede agregar un identificador al controlador de eventos para eliminar el controlador de eventos especificado
*/
Function Bind (DOM, Type, Fn, FnName) {
dom.eventqueue = dom.eventqueue || {};
dom.eventqueue [type] = dom.eventqueue [type] || {};
dom.handler = dom.handler || {};
if (! fnname) {
Var index = Queuelggth (DOM, Tipo);
dom.eventqueue [type] ['fnqueue'+index] = fn;
}
demás {
dom.eventqueue [type] [fnname] = fn;
};
if (! dom.handler [type]) bindEvent (dom, type);
};
/*Evento vinculante
*
*@param {dom-dom} y {type-string}
*@Ejecutar los eventos están vinculados solo una vez, el controlador se usa para atravesar los controladores de eventos (funciones) en la cola de eventos de ejecución
*@llamador bind ()
*/
función bindEvent (dom, type) {
dom.handler [type] = function () {
para (var guía en dom.eventqueue [type]) {
dom.eventqueue [type] [guía] .call (dom);
}
};
if (window.addeventListener) {
dom.addeventListener (type, dom.handler [type], falso);
}
demás {
dom.attachevent ('on'+type, dom.handler [type]);
};
};
/*Eliminar la interfaz para el evento
*
*@param {dom-dom} y {type-string} parámetros opcionales {fnname-function}
*@Ejecutar si no hay identificador, ejecutar Unbindevent ()
Si hay un identificador, se elimina el controlador de eventos especificado. Si la longitud de la cola de eventos es 0, no se ejecuta ().
*/
function nobind (dom, type, fnname) {
var Hasqueue = dom.eventqueue && dom.eventqueue [type];
if (! Hasqueue) regresar;
if (! fnname) {
sincintevente (DOM, tipo)
}
demás {
eliminar dom.eventqueue [type] [fnname];
if (queuelchenth (dom, type) == 0) noindevent (dom, type);
};
};
/*Eliminar el evento
*
*@param {dom-dom} y {type-string}
*@ejecutar elimina el controlador de eventos unido y borra la cola de eventos
*@Caller no admitir ()
*/
function noindevent (dom, type) {
if (window.removeEventListener) {
DOM.RemoveEventListener (type, dom.handler [type])
}
demás {
dom.detachevent (type, dom.handler [type])
}
eliminar dom.eventqueue [type];
};
/*Juez de la cola de eventos de eventos
*
*@param {dom-dom} y {type-string}
*@Caller bind () sinind ()
*/
function queuelcent longitud (dom, type) {
índice var = 0;
para (longitud var en dom.eventqueue [type]) {
índice ++;
}
Índice de retorno;
};
Cómo usar
La copia del código es la siguiente:
var obtn = document.getElementById ('btn');
// evento vinculante
// BINCE TRES FUNCIONES DE EVENTO DE HACIA
// La orden de ejecución bajo IE6-II8 permanece sin cambios
bind (OBTN, 'Click', function () {
alerta (1);
})
bind (OBTN, 'Click', function () {
alerta (2);
}, 'myfn')
bind (OBTN, 'Click', function () {
alerta (3);
})
// eliminar el evento
// Eliminar todas las funciones de evento de clic en el límite, admitir la eliminación de funciones anónimas
Desvantar (OBTN, 'Haga clic')
// eliminar solo las funciones de eventos con identificador myfn
no admite (obtn, 'hacer clic', 'myfn')
Ideas de programas
La idea principal del programa es agregar la cola de eventos como un atributo del objeto DOM Elemento al elemento DOM sin contaminar el entorno global. Esto puede resolver el problema del almacenamiento de datos de múltiples funciones de eventos de diferentes elementos DOM que se unen a diferentes tipos de eventos.
La copia del código es la siguiente:
// cola de eventos en el elemento DOM
DOM {
EventQueue: {
'Haga clic': {
fnqueue1: función,
myfn: función,
Fnqueue3: función
}
'Mouseover': {
fnqueue1: función,
Fnqueue2: función
}
}
}
Cada vez, la función del evento se agrega primero a la cola de eventos del tipo de evento correspondiente, y el evento solo está vinculado una vez. Cuando se activa un evento, se ejecuta la función del evento del controlador y el controlador atraviesa la función del evento en la cola de eventos de ejecución.
Unbind () elimina todas las funciones de eventos límite si no hay un identificador entrante, admite eliminar funciones anónimas y elimina las funciones de evento especificadas si hay un identificador.
La lógica del programa no es complicada, y puede haber errores y problemas de rendimiento. Si está interesado, puede guiar y comunicarse.