2010-02-19 9 views
7

Ich habe meinen Kopf in eine Wand gerannt und versucht, das herauszufinden. Nehmen Sie den folgenden HTML-Körper:Warum kann jQuery bestimmte HTML nicht verbergen?

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

Und die folgende jQuery-Code:

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

Der $(h).hide() Teil verursacht jQuery eine Ausnahme in Safari 4 und Firefox 3.5 zu werfen.

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

Wenn ich das HTML ändern, nur eine der beiden Positionen enthalten (wenn Sie die <h1> oder <h2> aus dem HTML entfernen, wird das Skript erfolgreich. Warum ist das?

für sich selbst versuchen, sehen http://jsbin.com/avisi/edit

Edit: Ich versuche nicht wirklich, Elemente aus dem DOM zu entfernen und wieder einzufügen, indem ich das HTML kopiere. Dies ist nur ein Testfall für einen Fehler, den ich in komplexeren Code habe, und ich versuche zu verstehen, warum dieser Fehler auftritt. Ich stimme dem zu, wenn ich nur das erreichen wollte, was hier gezeigt wird, würde ich etwas wie $('#project').remove().children().appendTo('body')

Antwort

7

arbeite ich Ihre Fehler in Firefox nicht duplizieren. Allerdings möchten Sie vielleicht versuchen Sie es mit der folgenden Reinigung:

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

Gegliedert ist das, was

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

Andere geschieht schlagen vor, dass .hide() wird Probleme, da der Knoten verursacht, dass es sein wird, angewandt auf ist nicht Teil des Hauptdokuments; Dies ist jedoch nicht der Fall. Solange Sie einen Verweis auf einen Knoten pflegen, können Sie seine Stileigenschaft beeinflussen (über hide, show, usw.).

Eine Sache, die Sie überprüfen sollten, ist sicherzustellen, dass $('#project') tatsächlich den (wenn überhaupt) erwarteten Knoten zurückgibt. Probleme können sich sonst ergeben.


Also stocherte ich in Safari und fand Ihr Problem. Hier ist ein Dump von der Entwicklerkonsole.

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

So weit, so gut. undefined hier bedeutet einfach, dass die Aussage (die var Anweisung) keinen Rückgabewert hat

> 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. 
(was es nicht tut)

Hier ist der Fehler, den Sie beschrieben.jedes Element in jQuery-Objekt Inspizieren den Fehler unter

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

Gut ...

> t[1] 
(whitespace) 

Dammit offenbaren. "Ja wirklich?" Hier ist das Problem. Leerzeichen haben kein style Attribut, was das Problem verursacht.

Deshalb ist es eine schlechte Technik, den HTML-Code eines Knotens in einen anderen zu kopieren, nur um diese Knoten zu verschieben. Ich schlage vor, dass Sie den Ausschnitt verwenden, den ich oben angegeben habe.

+0

Ich stimme zu, dass dies eine viel sauberere Möglichkeit ist, die fraglichen Knoten zu entfernen und wieder einzufügen. Ich versuche zu verstehen, warum (zumindest in meiner Version von Firefox 3.5 und Safari 4) dieser obige Code einen Fehler verursacht. – Ryan

+0

Ich habe die Ursache gefunden und meine Antwort aktualisiert. –

+0

Justin, danke für die Untersuchung. Ich bin mir sicher, dass ich damit mein erstes Problem lösen kann, das darin besteht, ein HTML-Fragment zu verstecken und einzufügen, das vom Server empfangen wurde (weshalb '.remove()' ... '.append()' nicht ist eine Option - es gibt nichts zu entfernen). – Ryan

-1

verwenden. Sie haben den Inhalt zuvor aus dem DOM entfernt, also gibt es nichts zu verbergen. Wenn Sie

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

tun würde, sollte es

+2

Es gibt etwas zu verbergen. Nur weil der Knoten aus dem Dokument entfernt wurde, heißt das nicht, dass er nicht existiert und dass keine Stilmanipulationen ausgeführt werden können. –

+0

Sie sind richtig, obwohl ich nicht ganz verstehe, was den Fehler dann auslöst. – harpax

+0

Siehe meine aktualisierte Antwort. –

1

In $ (h) ist ein Textknoten ausgewählt. Wir können das aber mit der Filterfunktion herausfiltern.

Dies sollte funktionieren (ich habe in FF obwohl nur getestet):

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

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

IMO recht sonderbares Verhalten.

+1

Es ist bedauerliches, aber erwartetes Verhalten. Wenn Sie DOM-Knoten aus einer HTML-Zeichenfolge erstellen, werden Leerzeichen zwischen den Knoten in Textknoten konvertiert. Dies verursacht oft Probleme, weshalb die Technik manchmal am besten zu vermeiden ist, insbesondere für die Zwecke des OP. –

Verwandte Themen