2010-02-19 5 views
7

J'ai couru la tête dans un mur en essayant de comprendre cela. Prenez le corps HTML suivant:Pourquoi jQuery ne parvient pas à masquer certains fichiers HTML?

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

Et le code jQuery suivant:

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

La partie $(h).hide() fait jQuery pour lancer une exception dans Safari 4 et 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: ...]

Quand je change le code HTML pour contenir seulement l'une des deux rubriques (si vous supprimez le script fonctionne avec succès <h1> ou <h2> du HTML,. Pourquoi est-ce

? pour essayer pour vous-même, voir http://jsbin.com/avisi/edit

Edit: Je ne suis pas en train d'essayer de supprimer et de supprimer un élément du DOM et de le réinsérer en copiant le code HTML. Ceci est juste un test pour une erreur que j'ai dans un code plus complexe, et j'essaie de comprendre pourquoi cette erreur se produit. Je suis d'accord que, si je voulais accomplir juste ce qui est montré ici, je voudrais utiliser quelque chose comme $('#project').remove().children().appendTo('body')

Répondre

7

Je ne peux pas dupliquer votre erreur dans Firefox. Cependant, vous pouvez essayer de le nettoyer avec les éléments suivants:

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

en panne, voici ce qui se passe

// 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(); 

D'autres proposent que .hide() pose des problèmes depuis le nœud qu'il est en cours appliqué à ne fait pas partie du document principal; Cependant, ce n'est pas le cas. Tant que vous conservez une référence à un nœud, vous pouvez affecter sa propriété de style (via hide, show, etc.).

Une chose que vous voudrez peut-être vérifier est de vous assurer que $('#project') renvoie effectivement le (le cas échéant) nœud attendu. Des problèmes peuvent survenir autrement.


J'ai donc fait le tour de Safari et j'ai trouvé votre problème. Voici un vidage de la console du développeur.

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

Jusqu'ici, tout va bien. undefined ici signifie simplement que la déclaration (la déclaration var) n'a pas de valeur de retour (ce qui ne fonctionne pas)

> 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. 

Voici l'erreur que vous avez décrit.Inspectant chaque élément objet jQuery révélera l'erreur ci-dessous

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

... Bonne

> t[1] 
(whitespace) 

Zut. Vraiment? Voici le problème. Les noeuds d'espaces n'ont aucun attribut style, ce qui est à l'origine du problème. C'est pourquoi la copie du code HTML d'un nœud vers un autre simplement pour déplacer ces nœuds est une mauvaise technique. Je vous suggère d'utiliser l'extrait que j'ai fourni ci-dessus.

+0

Je suis d'accord que c'est une façon beaucoup plus propre de supprimer et de réinsérer les nœuds en question. Ce que j'essaie de comprendre, c'est pourquoi (au moins dans ma copie de Firefox 3.5 et Safari 4), ce code ci-dessus provoque une erreur. – Ryan

+0

J'ai trouvé la cause et j'ai mis à jour ma réponse. –

+0

Justin, merci d'avoir enquêté là-dessus. Je suis sûr que je peux l'utiliser pour résoudre mon problème initial, qui essayait de cacher et d'insérer un fragment HTML reçu du serveur (c'est pourquoi '.remove()' ... '.append()' n'est pas une option - il n'y a rien à enlever). – Ryan

-1

Vous avez supprimé le contenu du DOM avant, donc il n'y a rien à cacher. Si vous ne

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

il devrait fonctionner

+2

Il y a quelque chose à cacher. Le fait que le noeud ait été supprimé du document ne signifie pas qu'il n'existe pas et qu'il ne peut pas faire l'objet de manipulations de style. –

+0

vous avez raison, mais je ne comprends pas très bien ce qui soulève l'erreur alors .. – harpax

+0

Voir ma mise à jour de la réponse. –

1

Un noeud de texte est sélectionné dans $ (h). Nous pouvons filtrer cela en utilisant la fonction de filtre.

Cela devrait fonctionner (je ne l'ai testé dans FF si):

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

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

comportement assez bizarre OMI.

+1

C'est un comportement regrettable mais attendu. Si vous créez des nœuds DOM à partir d'une chaîne HTML, les espaces entre les nœuds sont convertis en nœuds de texte. Cela pose souvent des problèmes, ce qui explique pourquoi il est parfois préférable d'éviter la technique, surtout aux fins du PO. –

Questions connexes