Es ist nicht möglich, thing.animate({ "height": "auto" }); durchzuführen. Das ist also die Methode von Darcy Clarke, um das zu ermöglichen. Sie klonen im Wesentlichen das Element, entfernen die festen Höhen, die das Element derzeit beeinträchtigen, und messen/speichern den Wert. Dann animieren Sie das reale Element auf diesen Wert.
jQuery.fn.animateAuto = function(prop, speed, callback){
var elem, height, width;
return this.each(function(i, el){
el = jQuery(el), elem = el.clone().css({"height":"auto","width":"auto"}).appendTo("body");
height = elem.css("height"),
width = elem.css("width"),
elem.remove();
if(prop === "height")
el.animate({"height":height}, speed, callback);
else if(prop === "width")
el.animate({"width":width}, speed, callback);
else if(prop === "both")
el.animate({"width":width,"height":height}, speed, callback);
});
}
Verwendung
$(".animateHeight").bind("click", function(e){
$(".test").animateAuto("height", 1000);
});
$(".animateWidth").bind("click", function(e){
$(".test").animateAuto("width", 1000);
});
$(".animateBoth").bind("click", function(e){
$(".test").animateAuto("both", 1000);
});
Wenn Sie ein Problem mit der Größenänderung haben, bei dem das Element (wenn es in der Größe geändert wird) größer als sein Elternteil ist, ersetzen Sie
mit
Wenn Sie versuchen, die Höhe von Inline-Elementen (wie einem Absatz) zu animieren, sollten Sie sicherstellen, dass Sie auch die Breite *nicht* auf auto ändern. Sie möchten diese Zeile ändern
zu
Ein Absatz ist ein Blockelement.
So sehr ich auch möchte, dass das funktioniert, ich bin jetzt auf zwei separaten Instanzen gestoßen, bei denen die Verwendung dieses Codes nicht funktioniert. Die Logik ist vollständig vorhanden – Klonen, Prüfen, dann Animieren – aber aus irgendeinem Grund ist es für mich frustrierend hartnäckig. Entweder bekomme ich Höhen, die viel zu groß oder viel zu klein sind. Ich habe anschließend zwei Workarounds dafür gefunden.
Das erste ist, den Inhalt natürlich laden zu lassen, die Höhen abzurufen, nachdem die Seite geladen wurde, und dann sofort eine Klasse hinzuzufügen, die die Box auf die gewünschte Höhe „verkleinert“. Es sieht ungefähr so aus.
Das setTimeout lässt die Webschriften laden, bevor die Höhen ermittelt werden: Es stellt sich heraus, dass diese in einigen Browsern erst ganz am Ende geladen werden und falsche Ergebnisse liefern. Dies funktioniert auch für Positionen und vermeidet auf ähnliche Weise die gleiche Fallstrick mit dem setTimeout. Dann, wenn die Zeit kommt, die Höhen zu nutzen, animieren Sie einfach auf den angegebenen Wert im Array.
Wenn Sie dem Element keinen Index zuweisen können oder wenn der Inhalt der Elemente dynamisch ist, geben Sie dem Element, das Sie animieren möchten, einfach einen Wrapper und setzen Sie dessen `overflow` auf `hidden`.
Animieren Sie dann den Wrapper auf die Höhe des inneren Elements, und es scheint, als würde es zur gegebenen Höhe animieren – dynamisch.
Ich bin sicher, es gibt programmatisch bessere Wege, beide Ansätze zu verfolgen, aber sie haben für mich wunderbar funktioniert.
Oh, und viel Liebe für diese Seite. Ich hoffe, ich kann Ihnen eines Tages ein Bier kaufen, Herr Coyier.
Es gibt meistens einen einfacheren Weg.
Anstatt zu versuchen, die Höhe zu animieren, animieren Sie `max-height`.
Wenn Sie sie ausblenden möchten, reicht `max-height:0px` aus, und wenn Sie sie anzeigen möchten, können Sie sie auf `max-height:10000px;` animieren... sie animiert dann auf ihre normale Höhe.
Stellen Sie einfach sicher, dass Sie `max-height` anstelle von `height` in Ihrer Übergangsdeklaration verwenden.
Steve, Sie wunderbarer Mann!
`Max-height` hat meine Welt auf eine gute Weise auf den Kopf gestellt. Konnte nicht einfacher sein.
Danke!
Kein Problem. Freut mich, dass es geholfen hat!
Musste einen Kommentar zum EINFACHEN Ansatz hinterlassen! Vielen Dank!
Liebe es – danke, Steve!
Hier ist ein einfaches jQuery, das ich mit `max-width` verwendet habe, um ein Menü in einem Div mit `onclick` anzuzeigen. Beachten Sie, dass jede Polsterung des Elements, das Sie anpassen, dazu führt, dass dieser Teil des Elements angezeigt wird. Was für meine Zwecke gut war (es ermöglichte die Anzeige des „«“ und „»“, die Sie in meinem Code sehen, worauf der Benutzer klickt, um das Menü ein- und auszublenden), aber wenn Sie das nicht möchten, dann stellen Sie sicher, dass Sie zusätzlichen Code hinzufügen, um Ihre Polsterung hinzuzufügen/zu entfernen.
Setzen Sie dann das Div initial auf
max-width: 0px;, wenden Sieonclick="toggleHorizontal('hidden_id', 'click_id')"an und voilà! Hoffentlich finden das einige so hilfreich, wie ich Steves Vorschlag fand.Wenn die Höhe jedoch gering ist, wird die Animation eine ernsthafte Verzögerung aufweisen. Wenn die Höhe bekannt ist, ist die Animation konsistenter.
Wow Steve, du hast mir gerade den Tag gerettet! Ich kann nicht glauben, dass ich diese Methode noch nie gehört habe, sie funktioniert perfekt. Danke!
Steve, du bist so großartig!
Ich liebe dich jetzt.
Hallo,
Jemand hatte ein ähnliches Problem und um es zu lösen, habe ich gerade auf Stack Overflow geschrieben.
http://stackoverflow.com/questions/1472303/jquery-get-width-of-element-when-not-visible-display-none/12114088#12114088
Das Problem mit dem Kopieren und Einfügen in das `body` ist, dass die tatsächliche Breite und Höhe etwas anderes sein könnte, sodass es wirklich vom CSS-Kontext (CSS-DOM-Position) abhängt. Wenn Sie es direkt in das `body` einfügen, könnte das DOM-Element außerhalb einiger übergeordneter CSS-Regeln liegen.
Ich habe keine robuste Lösung, die dieses Problem lösen könnte. Daher werde ich mir Shadow-DOM genauer ansehen (vielleicht kann das es robust machen).
Steve, das ist genial. Danke Chris, dass du das hervorgehoben hast, du bist auf der Höhe der Zeit.
Hallo, ich habe ein Problem mit diesem Skript! Wenn ich es in meine Website einfüge, bekomme ich immer diese Fehlermeldung: Object [object global] has no method ‘each’. Der Fehler liegt vielleicht in Zeile 3. Haben Sie eine Idee, wie man das lösen kann??
Stepan, hast du jQuery in dein Skript eingebunden?
Ich habe Ihren Code verwendet. Danke!
Ich musste Änderungen vornehmen, um eine allgemeine Bedenken auszuräumen.
Stellen Sie sich vor, bestimmte Stile werden nicht auf das geklonte Element angewendet, wenn es sich im `body` befindet, aber wenn es sich am ursprünglichen Ort befindet (z. B. ein Stil, der nur über die Klasse eines übergeordneten Elements angewendet wird).
Um dies zu lösen, habe ich den Klon an das Elternteil des Originals angehängt. Um einen Randfall-Blitz des Klonelements zu verhindern, habe ich
"visibility":"hidden"zur Methode.css(...)hinzugefügt.Ich habe auch
.removeAttr("id")auf dem geklonten Element ausgeführt, möglicherweise um zu verhindern, dass andere Plugins, die auf das Element wirken, auf den Klon wirken. Dies könnte eine Option für Parameter sein, denn vielleicht möchten Sie, dass das Element mit jedem Plugin synchron bleibt, das über die ID auf das Original wirkt.Vielen Dank nochmals für die Lösung meines Problems mit Ihrem Code.
Hallo,
Warum das Element klonen, um die Höhe zu erhalten, wäre es nicht einfacher (und schneller?), das Element vorübergehend zu positionieren (und anzuzeigen) weit links in seinem relativ positionierten Elternteil? Zum Beispiel durch Hinzufügen einer Klasse wie dieser zum Element.
Mehrere Probleme mit dem Originalcode.
Erstens werden die Elemente auf die gewünschte „auto“-Höhe oder -Breite animiert, korrekt, aber am Ende ist die Höhe oder Breite fest. Wenn sich also der Inhalt des Elements vergrößert, passt er sich nicht richtig an, wenn er das tun sollte, wenn die CSS-Höhe oder -Breite auf „auto“ gesetzt ist.
Zweitens wird das Klonelement immer an das `BODY` angehängt. Abhängig von Ihren DOM-CSS-Stilen ist dies möglicherweise nicht das, was Sie für den DOM-Standort beabsichtigt haben.
Ich habe einige Modifikationen am Code vorgenommen, um diese Probleme zu „beheben“.
Das erste Problem wird durch das Hinzufügen einer Zeile behoben, die die CSS auf „auto“ setzt, wie im Fall von `width`.
$(this).css({width: 'auto'});, nachdem die Animation abgeschlossen ist.Das zweite Problem wird durch
.insertAfter()des ursprünglichen Elements anstelle von.appendTo()des `BODY` behoben, wo der Kontext möglicherweise nicht die gewünschte „auto“-Höhe oder -Breite rendert. Es gibt jedoch immer noch eine Einschränkung dieser Korrektur, die von Ihrem CSS abhängt. Aber ich erwarte, dass das nur selten vorkommt.Wie auch immer, danke fürs Teilen des Codes, es hat mir Zeit gespart, ihn selbst zu schreiben. ^_^
Wenn jemand am Ende dieser Kommentare angekommen ist – ich versuche, eine zuverlässige Lösung für dieses nur allzu häufige Problem zu entwickeln, das auf Github veröffentlicht wird, nicht nur in einem Kommentar oder einem Blogbeitrag.
https://github.com/davidtheclark/jquery.animateAuto
Ich glaube, ich habe die Ideen integriert, die die Leute oben geteilt haben, sowie meine eigenen – und ich hoffe, dass andere zur Entwicklung einer absolut soliden, zuverlässigen und wiederverwendbaren Lösung beitragen wollen. Lassen Sie uns Anstrengungen bündeln.
Vielen Dank, Steve. Sie haben meinen Tag gerettet.
Die Funktion `animateToAutoHeight` funktioniert gut.
http://stackoverflow.com/questions/5003220/javascript-jquery-animate-to-auto-height
Steve, du bist großartig.
Wow..
Das bedeutet… ich bin auf dem gleichen Expertenniveau :P
Ich habe gerade dasselbe programmiert. Und nur um zu wissen, wie Leute das machen, um dieses Ergebnis zu erzielen, und ich habe Sie gefunden… :) Sie haben dasselbe programmiert…
Bedeutet das, dass ich ein guter Coder bin oder Sie nicht gut sind wie ich :)
danke
Vielen Dank für diesen Code. Sie haben mir das Leben gerettet.
Scheint, dass der Klon aufgrund seiner Positionierung im DOM/CSS-DOM einige Probleme verursacht. Habe ein paar kleine Änderungen am Skript vorgenommen, um sicherzustellen, dass Sie immer die „auto“-Höhe und -Breite erhalten, indem Sie einfach das Originalelement verwenden. Könnte für jemanden hilfreich sein. Außerdem wurden einige logische Standardwerte für `prop`, `speed` und `callback` hinzugefügt.