Tengo un código jQuery que adjunta repetidamente controladores delegados (por ejemplo click() ) a un elemento, de modo que cuando se activa el evento, se llama al controlador varias veces.
Conozco la solución estratégica: en mi escenario, el delegado debe ser el único elemento secundario del contenedor de código cargado con AJAX, de modo que cualquier reemplazo eliminará, junto con los elementos DOM, cualquier controlador que hayan delegado.
Otra posibilidad sería reescribir tales asignaciones como
$(...).off(event, selector).on(event, selector, event => { });para asegurar que nunca ocurra una doble delegación.
Lo que me gustaría es una solución táctica para advertirme a mí y a los otros desarrolladores de proyectos cuando hayan agregado (o dejado en su lugar, ya que este es un proyecto importante de reingeniería y limpieza de código) sin darse cuenta cualquier controlador delegado a objetos más arriba en el DOM árbol que el contenedor elegido. mi idea es:
+++ let before = app.developer.calculateHandlerSyndrome($('#container')); performObjectLoad('#container', whatever) .then(...) +++ .then(_ => { +++ if (before !== app.developer.calculateHandlerSyndrome($('#container'))) { +++ sys.error("The object " + whatever + " has over-delegated"); +++ } +++ }); Para mi calculateHandlerSyndrome($selector) , estoy pensando en devolver una serie de selectores, comenzando desde el especificado y trabajando hacia arriba recursivamente a través de todos los padres hasta que llegue a document . Para comparar las matrices, simplemente las JSON.stringify() .
Lo que me falta es un método para recuperar los controladores de eventos para un selector determinado, ya que el método $.data('events') parece no funcionar.
Encontré los eventos que necesito dentro de una propiedad de cada elemento DOM llamada "jQuery1234(ALARGENUMBER)56789", pero es obvio que el número es una identificación única y cambiará en cada carga de página. Podría verificar todas las propiedades de cada elemento y encontrar si hay uno llamado jQuery algo , pero es una solución demasiado complicada.
La jQuery.fn.data('events') está obsoleta y se reemplazó por $._data(element).events .
Entonces el enfoque sería:
function handlerSyndrome($selector) { let parent = $selector.parent(), syndrome = [ ]; if (parent.length) { syndrome = handlerSyndrome(parent); } // Get the element's handlers let ev = $._data($selector[0]).events; // Transform it to an object with count: { click: 7, blur: 2 }, ... let hnd = { }; for (const h in ev) { hnd[h] = ev[h].length; } if (Object.getOwnPropertyNames(hnd).length) { syndrome.push(hnd); } return syndrome; } Esto tomará un selector jQuery como $('#container') y devolverá algo como,
[ { "click": 20, "focusout": 1, "focusin": 1, "keydown": 2, "keyup": 1, "mouseup": 1, "mousedown": 1, "change": 2 }, { "click": 1 } ]y permitirá verificar si el árbol principal sobre ese selector tiene algo agregado a sus controladores. No comprobará si hay cambios o reordenamientos .
Puede ser necesario retrasar la llamada para verificar después de la carga usando window.setTimeout() .