2010-02-19 12 views
7

He estado corriendo la cabeza contra una pared tratando de resolver esto. Tome el siguiente cuerpo HTML:¿Por qué jQuery no puede ocultar cierto HTML?

<body> 
<div id="project"> 
    <h1>Hi</h1> 
    <h2>Hello</h2> 
</div> 
</body> 

Y el siguiente código de jQuery:

$(function(){ 
    var h = $('#project').html(); 
    $('#project').remove(); 
    $(h).hide().appendTo('body'); 
    alert("Created HTML, hide, and appended!"); 
}); 

La parte $(h).hide() causa jQuery para lanzar una excepción en Safari 4 y Firefox 3.5.

Safari:TypeError: Result of expression 'this[a].style' [undefined] is not an object.
Firefox:uncaught exception: [Exception... "Could not convert JavaScript argument arg 0" nsresult: ...]

Cuando cambio el código HTML para contener sólo una de las dos partidas (si se quita el <h1> o <h2> del HTML, la secuencia de comandos se ejecuta correctamente. ¿por qué es esto?

para probar por ti mismo, ver http://jsbin.com/avisi/edit

Editar: En realidad, no estoy tratando de eliminar y elemento del DOM y volver a insertarlo copiando el HTML. Este es solo un caso de prueba para un error que estoy teniendo en un código más complejo, y estoy tratando de entender por qué ocurre este error. Estoy de acuerdo en que, si quisiera lograr lo que se muestra aquí, usaría algo como $('#project').remove().children().appendTo('body')

Respuesta

7

no puedo duplicar su error en Firefox. Sin embargo, es posible que desee para tratar de limpiarlo con lo siguiente:

$('#project').remove().children().appendTo('body').hide(); 

desglosado, esto es lo que está pasando

// Get the `project` container 
$('#project') 
    // Remove it from the page 
    .remove() 
    // Get its children (the h1, h2, etc) 
    .children() 
    // Append those nodes to the body 
    .appendTo('body') 
    // Hide those nodes 
    .hide(); 

Otros proponen que .hide() está causando problemas desde el nodo que está siendo aplicado a no es parte del documento principal; sin embargo, este no es el caso. Siempre que mantenga una referencia a cualquier nodo, puede afectar su propiedad de estilo (a través de hide, show, etc.).

Una de las cosas que tal vez quiera comprobar es asegurarse de que $('#project') devuelve realmente el nodo esperado (si lo hay). Los problemas pueden surgir de lo contrario.


Así que hurgó en Safari y encontró su problema. Aquí hay un volcado de la consola de desarrollador.

> var h = $('#project').html(); 
undefined 
> var t = $(h); 
undefined 

Hasta ahora, muy bien. undefined aquí simplemente significa que el estado (el estado var) no tiene valor de retorno (que no lo hace)

> t.hide() 
ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.min.js:131TypeError: Result of expression 'this[a].style' [undefined] is not an object. 

Aquí está el error que has descrito.La inspección de cada elemento de objeto jQuery revelará el error abajo

> t[0] 
<h1 style=​"display:​ none;​ ">​Hi​</h1> 

Bueno ...

> t[1] 
(whitespace) 

Dammit. De Verdad? Este es el problema. los nodos de espacio en blanco no tienen el atributo style, que es lo que está causando el problema.

> t[2] 
<h2>​Hello​</h2> 

Es por eso que copiar el código HTML de un nodo a otro solo para mover esos nodos es una mala técnica. Sugiero que use el fragmento que proporcioné arriba.

+0

Acepto que esta es una forma mucho más limpia de eliminar y volver a insertar los nodos en cuestión. Lo que intento entender es por qué (al menos en mi copia de Firefox 3.5 y Safari 4), este código anterior causa un error. – Ryan

+0

Encontré la causa y actualicé mi respuesta. –

+0

Justin, gracias por investigar esto. Estoy seguro de que puedo usar esto para resolver mi problema inicial, que fue tratar de ocultar e insertar un fragmento de HTML recibido del servidor (razón por la cual '.remove()' ... '.append()' no es una opción - no hay nada que eliminar). – Ryan

-1

Has eliminado el contenido del DOM anterior, por lo que no hay nada que ocultar. Si desea hacer

$(h).appendTo('body').hide(); 

que debería funcionar

+2

Hay algo que ocultar. El hecho de que el nodo se haya eliminado del documento no significa que no exista y que no se puedan realizar manipulaciones de estilo en él. –

+0

tiene la razón, aunque no entiendo muy bien qué causa el error, entonces ... – harpax

+0

Ver mi respuesta actualizada. –

1

Hay un nodo de texto seleccionado en $ (h). Sin embargo, podemos filtrar eso usando la función de filtro.

Esto debería funcionar (sólo lo he probado en FF sin embargo):

$(function(){ 
    var h = $('#project').html(); 
    $('#project').remove(); 
    $(h).filter("*").hide().appendTo('body'); 

alert("Created HTML, hide, and appended!"); 
}); 

comportamiento Bastante extraño OMI.

+1

Es un comportamiento desafortunado pero esperado. Si crea nodos DOM a partir de una cadena HTML, el espacio en blanco entre los nodos se convierte en nodos de texto. Esto a menudo causa problemas, razón por la cual la técnica a veces es mejor evitarla, especialmente para los propósitos de la OP. –

Cuestiones relacionadas