poner obtiene objeto letras las fuente forma eventos elementos dinámicamente dinámica creados creado como color carga cambiar bootstrap asociar asincrona acceso javascript jquery events mutation-events

javascript - obtiene - Forma preferida de modificar elementos que aún no se han creado(además de los eventos)



eventos html javascript (5)

Bueno, antes que nada, ni siquiera deberías estar usando selectores como este si te preocupa perforar.

$(''input[type=text], input[type=password], textarea, .basic_form .block select, .order_form .form_item select, .order_form .form_item input'')

Cualquier navegador que no tenga implementaciones nativas de xpath (más que solo IE iirc) o getElementsByClassName (IE 7 y siguientes) fácilmente podría pasar unos segundos mordisqueándolo en un sitio grande, por lo que las encuestas quedarían completamente descartadas. si lo quieres tan amplio.

Hay muchas preguntas sobre la vinculación de manipulaciones futuras a elementos inexistentes que todos terminan respondidos con live / delegate . Me pregunto cómo ejecutar una devolución de llamada arbitraria (para agregar una clase o activar un complemento, por ejemplo) a todos los elementos existentes que coinciden con un selector y todos los elementos futuros que coinciden con el mismo selector que aún no se han creado.

Parece que la funcionalidad principal del plugin livequery lo convirtió en el núcleo, pero la otra parte, uniendo devoluciones de llamada arbitrarias se perdió en el camino de alguna manera.

Otra respuesta común es la delegación de eventos, pero ¿qué ocurre si no se tiene acceso a todo el código de proveedor que está creando los elementos para que trigger los eventos?

Aquí hay un código del mundo real:

// with livequery $(''input[type=text], input[type=password], textarea, .basic_form .block select, .order_form .form_item select, .order_form .form_item input'') .livequery(function(){ $(this) .focus(function(){ $(this).addClass(''active''); }) .blur(function(){ $(this).removeClass(''active''); }) .addClass(''text''); }); // with live $(''input[type=text], input[type=password], textarea, .basic_form .block select, .order_form .form_item select, .order_form .form_item input'') .live(''focus'', function(){ $(this).addClass(''active''); }) .live(''blur'', function(){ $(this).removeClass(''active''); }); // now how to add the class to future elements? // (or apply another plugin or whatever arbitrary non-event thing)

Un enfoque sería monitorear cuándo se agregan / eliminan nuevos nodos y volver a activar nuestros selectores. Gracias a @arnorhs sabemos sobre el evento DOMNodeInserted , que ignoraría los problemas del navegador cruzado con la esperanza de que esos pequeños parches de IE algún día puedan llegar río arriba a jQuery o saber que las funciones DOM de jQuery podrían ser incluidas.

Incluso si pudiéramos asegurarnos de que DOMNodeInserted disparara el navegador cruzado, sin embargo, sería ridículo enlazarlo con múltiples selectores. Cientos de elementos se pueden crear en cualquier momento y hacer que se rastreen potencialmente docenas de llamadas de selector en cada uno de esos elementos.

Mi mejor idea hasta el momento

¿Sería tal vez mejor monitorear DOMNodeInserted / Deleted y / o enganchar en las rutinas de manipulación de DOM de jQuery para solo establecer un indicador de que debería ocurrir un "reinicio"? Entonces podría haber un temporizador que verifique ese indicador cada x segundos, solo ejecutando todos esos selectores / devoluciones cuando el DOM realmente haya cambiado.

Eso podría ser realmente malo si agregas / eliminas elementos en grandes cantidades a gran velocidad (como con animación o ____). Tener que volver a analizar el DOM una vez para cada selector guardado cada x segundos podría ser demasiado intenso si x es bajo, y la interfaz parecería lenta si x es alta.

¿Alguna otra solución novedosa?

Agregaré una recompensa cuando me lo permita. ¡He añadido una recompensa por la solución más novedosa!

Básicamente, a lo que me refiero es a un enfoque más orientado a los aspectos para manipular el DOM. Uno que puede permitir que los elementos nuevos se creen en el futuro , y deben crearse con las modificaciones iniciales del documento . También se les aplican modificaciones .

JS ha podido hacer tanta magia últimamente que espero que sea obvio.


En mi opinión, los eventos DOM Level 3, la DOMNodeInsertedhelp (que se DOMNodeInsertedhelp solo para los nodos) y la DOMSubtreeModifiedhelp (que se DOMSubtreeModifiedhelp para prácticamente cualquier modificación, como los cambios de atributos) son la mejor opción para realizar esa tarea.

Por supuesto, la gran desventaja de esos eventos es que los Exploradores de Internet de este mundo no los apoyan
(... bueno, IE9 lo hace).

La otra solución razonable para este problema, es enganchar en cualquier método que pueda modificar el DOM. Pero luego tenemos que preguntar, ¿cuál es nuestro alcance aquí?

¿Es suficiente lidiar con los métodos de modificación DOM de una biblioteca específica como jQuery? ¿Qué sucede si por alguna razón otra biblioteca modifica el DOM o incluso un método nativo?

Si es solo para jQuery, no necesitamos .sub() en absoluto. Podríamos escribir ganchos en la forma de:

HTML

<div id="test">Test DIV</div>

JS

(function(_append, _appendTo, _after, _insertAfter, _before, _insertBefore) { $.fn.append = function() { this.trigger({ type: ''DOMChanged'', newnode: arguments[0] }); return _append.apply(this, arguments); }; $.fn.appendTo = function() { this.trigger({ type: ''DOMChanged'', newnode: this }); return _appendTo.apply(this, arguments); }; $.fn.after = function() { this.trigger({ type: ''DOMChanged'', newnode: arguments[0] }); return _after.apply(this, arguments); }; // and so forth }($.fn.append, $.fn.appendTo, $.fn.after, $.fn.insertAfter, $.fn.before, $.fn.insertBefore)); $(''#test'').bind(''DOMChanged'', function(e) { console.log(''New node: '', e.newnode); }); $(''#test'').after(''<span>new span</span>''); $(''#test'').append(''<p>new paragraph</p>''); $(''<div>new div</div>'').appendTo($(''#test''));

Un ejemplo en vivo del código anterior se puede encontrar aquí: http://www.jsfiddle.net/RRfTZ/1/

Esto, por supuesto, requiere una lista completa de los métodos DOMmanip. No estoy seguro si puede sobreescribir métodos nativos como .appendChild() con este enfoque. .appendChild se encuentra en Element.prototype.appendChild por ejemplo, podría valer la pena intentarlo.

actualizar

Element.prototype.appendChild sobrescribir Element.prototype.appendChild etc. en Chrome, Safari y Firefox (último lanzamiento oficial). Funciona en Chrome y Safari, pero no en Firefox.

Puede haber otras formas de abordar el requisito. Pero no puedo pensar en un solo enfoque que sea realmente satisfactorio, como contar / ver todos los descendientes de un nodo (que necesitaría un interval o timeouts , eeek).

Conclusión

Una mezcla de eventos DOM Nivel 3 donde los métodos DOMmanip compatibles y enganchados es probablemente lo mejor que puedes hacer aquí.


Estaba leyendo sobre el nuevo lanzamiento de jQuery, versión 1.5 e inmediatamente pensé en esta pregunta.

Con jQuery 1.5 puedes crear tu propia versión de jQuery usando algo llamado jQuery.sub ();

De esta forma, puede anular las funciones predeterminadas .append (), insert (), .html (), .. en jQuery y crear su propio evento personalizado llamado algo así como "mydomchange", sin que afecte a todos los demás scripts.

Entonces puede hacer algo como esto (copiado de la documentación .sub () con un mod menor):

var sub$ = jQuery.sub(); sub$.fn.insert = function() { // New functionality: Trigger a domchange event this.trigger("domchange"); // Be sure to call the original jQuery remove method return jQuery.fn.insert.apply( this, arguments ); };

Tendría que hacer esto a todos los métodos de manipulación dom ...

jQuery.sub () en la documentación de jQuery: http://api.jquery.com/jQuery.sub/



No hay una forma simple y obvia de hacerlo. El único enfoque infalible es el sondeo activo, lo que provoca que se produzca un contratiempo entre el momento en que se crea el nuevo elemento y cuando el sondeo lo detecta. Eso también puede hacer que su página tome muchos recursos dependiendo de la frecuencia con que sondee la página. También puede acoplar esto, como observó, vinculando varios eventos específicos del navegador para al menos hacer que las cosas funcionen mejor en esos navegadores.

Puede anular las funciones de modificación DOM de jQuery para desencadenar un evento de cambio personalizado (y usar $ .live para capturar esos eventos para su manipulación), pero cuando lo intenté en el pasado, se rompieron sutilmente varios plugins de jQuery (mi suposición es que algunos esos complementos hacen algo similar). Al final, he renunciado a hacerlo de manera confiable, ya que no quiero renunciar a la actuación y dejar de tener problemas para la votación activa, y no hay otra forma integral de hacerlo. En su lugar, tengo un evento de inicialización que aseguro desencadenar para cada cambio de DOM que realizo, y en lugar de eso, uniré mis eventos de manipulación.

Tenga cuidado, es fácil quedar atrapado en un ciclo infinito de eventos si no piensa detenidamente, y esto también puede ser sutil y difícil de rastrear; y peor aún puede suceder en un caso de esquina que su unidad de prueba no permitió (para que los usuarios lo experimenten en lugar de solo usted). El evento personalizado de inicialización desencadenada manualmente es más fácil de diagnosticar en este sentido, ya que siempre sabe exactamente cuándo lo está activando.