2010-05-27 14 views
14

Todavía estoy buscando una respuesta.CSS no se aplica a los elementos creados dinámicamente en IE 7?

Al cambiar o reasignar al filtro innerHTML, se vuelve a dibujar el elemento con éxito, pero se rompe el guión, por lo que queda fuera.

La adición de nodos secundarios adicionales, incluidos los nodos de texto, no obliga a un redibujado. Eliminar el nodo agregado no obliga a volver a dibujar.

El uso de la familia de scripts ie7.js no funciona.


En el proyecto que estoy trabajando, me generan dinámicamente (con javascript) filtros que tener este aspecto:

<div class="filter"> 
    <a ... class="filter_delete_link">Delete</a> 
    <div class="filter_field"> 
     ... 
    </div> 
    <div class="filter_compare"> 
     ... 
    </div> 
    <div class="filter_constraint"> 
     ... 
    </div> 
    <div class="filter_logic"> 
     ... 
    </div> 
</div> 

y no tengo CSS que se aplica a cada filtro (por ejemplo):

.filter a.filter_delete_link{ 
    display:block; 
    height:16px; 
    background: url('../images/remove_16.gif') no-repeat; 
    padding-left:20px; 
} 

Sin embargo, parece que en IE 7 (y probablemente 6 para el caso), estos estilos no se aplican a los nuevos filtros.

Todo funciona perfectamente en Firefox/Chrome/IE8.

Utilizando las herramientas de desarrollador de IE8, establezca el modo IE7, el navegador puede ver los nuevos elementos, y puede ver el CSS, pero simplemente no está aplicando el CSS.

¿Hay alguna manera de obligar a IE a volver a cargar estilos, o quizás hay una mejor manera de arreglar esto?


La JavaScript: (simplificado)

var builder = { 
    ... 
    createNewFilter: function() { 
     var newFilter = document.createElement('div'); 

     var deleteLink = document.createElement('a'); 
     deleteLink.href = '#'; 
     deleteLink.setAttribute('class','filter_delete_link'); 
     deleteLink.title = 'Delete Condition'; 
     deleteLink.innerHTML = "Delete"; 
     newFilter.appendChild(deleteLink); 

     var field = document.createElement('div'); 
     field.setAttribute('class','filter_field'); 
     var fieldSelect = this.getFieldSelectBox(); 
     field.appendChild(fieldSelect); 
     newFilter.appendChild(field); 

     // more of the same... 

     deleteLink.onclick = function() { 
      builder.removeFilter(newFilter); 
     }; 
     fieldSelect.onchange = function() { 
      builder.updateFilter(newFilter); 
     } 

     return newFilter; 
    }, 
    addNewFilter: function() { 
     var nNewFilter = this.createNewFilter(this.numFilters++); 
     this.root.insertBefore(nNewFilter,this.nAddLink); 

     //other unrelated stuff... 

     //provided by Josh Stodola 
     //redraw(this.root); 

     return nNewFilter; 
    } 
} 
+0

En su página real, ¿tiene múltiples valores de "clase"? IE puede ser bastante estúpido con las reglas ".foo .bar" cuando el contenedor y el contenedor tienen valores múltiples en la "clase". – Pointy

+0

Puntiaguda, no uso múltiples clases, y exactamente por esa razón :) Incluso traté de simplificar el CSS para simplemente '.filter_delete_link', pero no voy. –

+0

IE6 tiene problemas con varias clases, IE7 no debería. –

Respuesta

23

El problema, he descubierto es que IE 6/7 no registra los cambios de nombre de clase con elm.setAttribute('class','x') hasta que se vuelve a dibujar la IU.

La solución es utilizar la forma elm.className = 'x'

** Este problema también fue notable pasen de peculiaridades IE9 a modo de estándares. La solución fue la misma.

+0

Gracias por publicar, luché con este tedioso poco por un tiempo. – montrealist

+0

Gracias, esto también solucionó mi problema. – Polaris878

+0

¡Muchas gracias! Estado buscando horas para esta solución –

0

Podría ser que se está perdiendo "al final de algunos elementos

<a ... class="filter_delete_link>Delete</a> missing " 
<div class="filter_field> missing " 
+0

Sólo un error tipográfico. Corregido ahora. –

0

usted tiene un faltante "? en la línea que dice <a ... class="filter_delete_link>Delete</a>

Edit:
No creo que sea un problema con IE7 ya que parece funcionar bien aquí - http://jsfiddle.net/nhvrA/.
Seguiré investigando.

+0

no, solo un error tipográfico. Corregido ahora. –

+0

No estoy usando jQuery (me gustaría estar, * gruñir, gruñir *). Quizás jQuery tiene algún código para volver a cargar estilos? –

1

IE6/7 tiene un montón de problems/bugs/misbehaviours con respecto a la creación y adición de elementos en el DOM usando createElement. Recomiendo encarecidamente cambiar a jQuery para esto, ya que hace todo el trabajo de una manera compatible con el navegador cruzado y ya ha tomado (casi) todos los malos comportamientos específicos de IE6/7 en cuenta para que no tenga que terminar con un duplicado cantidad de código para que funcione en todos los navegadores que el mundo conoce. He aquí una copy'n'paste'n'runnable SSCCE:

<!doctype html> 
<html lang="en"> 
    <head> 
     <title>Test</title> 
     <script src="http://code.jquery.com/jquery-latest.min.js"></script> 
     <script> 
      $(document).ready(function() { 
       $('#add').click(function() { 
        var newElement = $('<div class="filter"><a href="#" class="delete">delete</a></div>'); 
        $('#container').append(newElement); 
       }); 
      }); 
     </script> 
     <style> 
      .filter { background: pink; } 
      .delete { background: yellow; } 
     </style> 
    </head> 
    <body> 
     <div id="container"></div> 
     <button id="add">add</button> 
    </body> 
</html> 

actualización: según los comentarios, jQuery no es absolutamente una opción. Bueno, lo mejor que puedes probar es establecer atributos de elemento solo después de el elemento se ha agregado al DOM. También trate de no clonar nodos en IE6/7, esto es a menudo épico.Más bien crea un nuevo nodo desde el principio.

+0

Desearía poder cambiar a jQuery, es lo que normalmente uso. Sin embargo, no es una opción ahora :( –

+1

¿Por qué no? De todos modos, intente establecer los atributos del elemento * después de * que el elemento se haya agregado al DOM. También intente no clonar nodos en IE6/7, esto a menudo es un error épico. en lugar de crear un nuevo nodo desde el que comienza el. – BalusC

+0

Bien, estoy añadiendo atributos antes, y la clonación, así que voy a tratar de arreglar eso. –

4

me suena como que necesita para forzar un redibujo de la interfaz de usuario para este elemento. Hay varias maneras de hacer esto, pero el siguiente es el método más eficaz ...

// elm is a reference to your element 
var disp = elm.style.display; 
elm.style.display = "none"; 
var redrawFix = elm.offsetHeight; 
elm.style.display = disp; 

Aquí es otro método I found on Ajaxian ...

function redraw(elm) { 
    var n = document.createTextNode(' '); 
    elm.appendChild(n); 
    setTimeout(function(){ n.parentNode.removeChild(n) }, 0); 
    return elm; 
} 
+0

bueno, el primer método no funciona, y el segundo método falla porque IE no sabe qué ' Function.prototype.defer' es. –

+0

@ Austin Whoops, tienes razón. 'Defer' es una función Prototype (JS framework) que contiene la función de llamada hasta que el intérprete esté inactivo. He actualizado mi respuesta para no depender de esa función de marco, pero en su lugar use un método similar. –

+0

Entiendo lo que estás tratando de hacer. Sin embargo, no está funcionando. Traté de cambiar el tiempo de espera para esperar más tiempo, y no funcionó. Intenté simplemente dejar el nodo adicional adentro. Sin resultado. Lo que sí funciona es 'elm.innerHTML + = '';', pero eso arruina mis eventos (no estoy seguro por qué), así que necesito deshacerme del espacio. –

0

¿No necesitas una anchura, así como una altura en el elemento? Sé mostrar: bloque debería darle ancho: 100%, pero IE no es tan brillante. ¿Hay algo que cambie si proporciona un ancho?

+0

De hecho, le doy un ancho en otro estilo. –

0

edificio fuera de otros comentarios y respuestas en este tema, que resuelve este problema utilizando la librería Prototype:

<div id"dynamically-added-block"> ... </div> 
... 
$("dynamically-added-block").up().show(); 

Simplemente, conseguir que el padre y re-mostrarlo. Probado en IE8, utilizando ambos modos de navegador: IE8, modo de documento: IE8 y modo de navegador: IE7, modo de documento: IE7. No he probado con el temible modo peculiar.

+0

Encontrado esta referencia: http://www.evotech.net/blog/2009/03/ie8-css-support/ sugiriendo que se necesita la siguiente etiqueta meta:

Cuestiones relacionadas