Cómo copiar un nodo DOM con detectores de eventos?

Traté de

node.cloneNode(true); //deep copy

No parece copia de los detectores de eventos que he añadido el uso de node.addEventListener("click", someFunc);.

Utilizamos el Dojo de la biblioteca.

4 Kommentare

  1. 66

    cloneNode() no copia los detectores de eventos. De hecho, no hay ninguna manera de conseguir el asimiento de los detectores de eventos a través de la DOM, una vez que han sido conectados, por lo que sus opciones son:

    • Agregar todos los detectores de eventos de forma manual a su clonado nodo
    • Refactorizar el código para utilizar el evento de la delegación a fin de que todos los controladores de eventos están conectados a un nodo que contiene el original y el clon
    • El uso de una función de contenedor alrededor de Node.addEventListener() de seguir la pista de los oyentes añadido a cada nodo. Esta es la forma en jQuery clone() método es capaz de copiar un nodo con sus detectores de eventos, por ejemplo.
    • No te odio cuando los malos hábitos (en línea javascript como onclick) son más útiles que al propio vainilla alternativa? Suspiro…
    • La gente en general el uso de malas prácticas porque están más a la mano, no les hace bien.
    • Tal vez un ejemplo de código de cómo añadir detectores de eventos para el clonado de código?
    • usted tendría que saber que los eventos de los oyentes fueron añadidos en el primer lugar, y también tiene acceso al código del lugar donde usted ha hecho de la clonación, para asignar las devoluciones de llamada de nuevo, puesto que el acceso a las devoluciones de llamada puede ser complicado dependiendo de donde la clonación tuvo lugar en el código, así que un ejemplo será inútil, ya que hay demasiados escenarios.
    • En la actualidad se enfrentan con este problema. Parece que cloneNode se comporta bastante complicado cuando estamos hablando acerca de los detectores de eventos de copia: It does not copy event listeners added using addEventListener() or those assigned to element properties (e.g., node.onclick = fn).
  2. 2

    Evento Delegación ejemplo.

    Después de la lectura de Tim Abajo la respuesta, he encontrado delegada eventos que son muy fáciles de implementar, la resolución de un problema similar que tenía. Yo quisiera añadir un ejemplo concreto, aunque en JQuery no Dojo.

    Estoy re-skining una aplicación en la Semántica de la interfaz de usuario, que requiere de una pequeña pieza de JS para hacer que el mensaje de cierre de los botones. Sin embargo, los mensajes son clonado a partir de una plantilla de HTML etiqueta con document.importNode en una biblioteca. Esto significa que aún si hice adjuntar los controladores de eventos para la plantilla en el nuevo HTML, que se pierden durante la clonación.

    No puedo hacer de Tim opción 1, simplemente vuelva a conectar durante la clonación como la mensajería de la biblioteca es de front-end framework agnóstico. (Curiosamente mi anterior front-end fue en Zurb Foundation, que utiliza una «base de datos-se pude cerrar» atributo, la funcionalidad de la que no sobreviven el proceso de clonación).

    La control normal de eventos fue sugerido como este:

    $('.message .close').on('click', function() {
        $(this)
        .closest('.message')
        .transition('fade');
    });

    El problema de ser «.mensaje» en la aplicación de la carga sólo coincide con la sola plantilla, no el número de mensajes que llegan más tarde a través de la web sockets.

    Haciendo de esta delegada, significaba adjuntando el caso de que el contenedor en el que los mensajes se clonado <div id="user-messages">

    Por lo que se convierte en:

    $('#user-messages').on('click', '.message .close', function() {
        $(this)
        .closest('.message')
        .transition('fade');
    });

    Esto funcionó de inmediato, el ahorro de cualquier obra compleja como la tercera opción de envolver el caso de los submarinos.

    La Dojo equivalente se ve bastante similar en cuanto a concepto.

  3. 0

    Esto es lo que @JeromeJ estaba describiendo en un comentario. Crear el elemento inicial utilizando este código HTML.

    <DIV ONCLICK="doSomething(this)">touch me</DIV>

    Cuando clon de este elemento, el resultado será el mismo controlador, y «este» se seleccione el elemento clonado.

    Sería genial si el ONCLICK podría ser fácilmente añadidos en JavaScript. Este enfoque significa que usted tiene que escribir parte de su código en HTML.

  4. -1

    Esto no responde a la pregunta exactamente, pero si el caso de uso permite movimiento el elemento más que copia, puede utilizar removeChild junto con appendChild que preservará los detectores de eventos. Por ejemplo:

    function relocateElementBySelector(elementSelector, destSelector) {
      let element = document.querySelector(elementSelector);
      let elementParent = element.parentElement;
      let destElement = document.querySelector(destSelector);
      elementParent.removeChild(element);
      destElement.appendChild(element);
    }

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Recent Articles

Python «set» con duplicados/elementos repetidos

Hay una forma estándar de representar un "conjunto" que puede contener elementos duplicados. Como yo lo entiendo, un conjunto tiene exactamente un cero o...

Python: generador de expresión vs rendimiento

En Python, ¿hay alguna diferencia entre la creación de un generador de objetos a través de un generador de expresión versus el uso de...

Cómo exportar/importar la Masilla lista de sesiones?

Hay una manera de hacer esto? O tengo que tomar manualmente cada archivo de Registro? InformationsquelleAutor s.webbandit | 2012-10-23

no distingue mayúsculas de minúsculas coincidentes en xpath?

Por ejemplo, para el xml a continuación <CATALOG> <CD title="Empire Burlesque"/> <CD title="empire burlesque"/> <CD...