Ich habe das folgende Beispiel-HTML, es gibt einen DIV, der 100% Breite hat. Es enthält einige Elemente. Während der Größenänderung von Fenstern können die inneren Elemente neu positioniert werden, und die Abmessung des Div kann sich ändern. Ich frage, ob es möglich ist, das Dimensionsänderungsereignis des Div zu verknüpfen. und wie geht das? Ich binde derzeit die Rückruffunktion an das jQuery-Größenänderungsereignis auf dem Ziel-DIV. Es wird jedoch kein Konsolenprotokoll ausgegeben, siehe unten:
<html>
<head>
<script type="text/javascript" language="javascript" src="http://code.jquery.com/jquery-1.6.1.min.js"></script>
<script type="text/javascript" language="javascript">
$('#test_div').bind('resize', function(){
console.log('resized');
});
</script>
</head>
<body>
<div id="test_div" style="width: 100%; min-height: 30px; border: 1px dashed pink;">
<input type="button" value="button 1" />
<input type="button" value="button 2" />
<input type="button" value="button 3" />
</div>
</body>
</html>
javascript
jquery
html
William Choi
quelle
quelle
setInterval
hier als mögliche Lösung verwenden. Sie können jederzeitclearInterval
an einen Knopfdruck binden , um die Schleife zu stoppen, sobald Ihre Arbeit erledigt ist.Antworten:
Es gibt eine sehr effiziente Methode, um festzustellen, ob die Größe eines Elements geändert wurde.
http://marcj.github.io/css-element-queries/
Diese Bibliothek verfügt über eine Klasse
ResizeSensor
, die zur Größenänderungserkennung verwendet werden kann.Es verwendet einen ereignisbasierten Ansatz, ist also verdammt schnell und verschwendet keine CPU-Zeit.
Beispiel:
Verwenden Sie das jQuery onresize-Plugin nicht, da es
setTimeout()
in Kombination mit dem Lesen des DOMclientHeight
/ derclientWidth
Eigenschaften in einer Schleife verwendet wird, um nach Änderungen zu suchen .Dies ist unglaublich langsam und ungenau, da es zu Layout-Thrashing führt .
Offenlegung: Ich bin direkt mit dieser Bibliothek verbunden.
quelle
requestAnimationFrame
vssetTimeout
ist irrelevant, diese Bibliothek führt keine Schleife durch .requestAnimationFrame
wird nur zum Entprellen / Drosseln der Häufigkeit von Rückrufen verwendet, es wird nicht abgefragt . MutationObserver könnte theoretisch ähnlich verwendet werden, jedoch nicht in älteren Browsern. Das ist außerordentlich klug.Ein neuer Standard hierfür ist die Resize Observer-API, die in Chrome 64 verfügbar ist.
Größe des Beobachters ändern
Spezifikation: https://wicg.github.io/ResizeObserver
Polyfills: https://github.com/WICG/ResizeObserver/issues/3
Firefox-Problem: https://bugzil.la/1272409
Safari-Problem: http://wkb.ug/157743
Aktueller Support: http://caniuse.com/#feat=resizeobserver
quelle
Sie müssen das
resize
Ereignis an das bindenwindow
Objekt , nicht an ein generisches HTML-Element.Sie könnten dann Folgendes verwenden:
und innerhalb der Rückruffunktion können Sie die neue Breite Ihres
div
Anrufs überprüfenDie Antwort auf Ihre Frage lautet also nein . Sie können das
resize
Ereignis nicht an ein div binden .quelle
Langfristig können Sie die ResizeObserver verwenden .
Leider wird es derzeit in vielen Browsern nicht standardmäßig unterstützt.
In der Zwischenzeit können Sie folgende Funktionen verwenden. Da die meisten Änderungen der Elementgröße auf die Größenänderung des Fensters oder auf Änderungen im DOM zurückzuführen sind. Sie können Fenster hören mit dem Fenster der Größe ändern Resize - Ereignis und Sie können hören DOM ändert MutationObserver .
Hier ist ein Beispiel für eine Funktion, die Sie zurückruft, wenn sich die Größe des bereitgestellten Elements aufgrund eines dieser Ereignisse ändert:
quelle
body
wie in diesem Beispiel zu sehen, können Sie ein Element direkt ansehen. Das ist tatsächlich performanter und effizienter als den ganzen Körper zu beobachten.ResizeSensor.js ist Teil einer großen Bibliothek, aber ich reduzierte seine Funktionalität zu THIS :
Wie man es benutzt:
quelle
parseInt( getComputedStyle(element) )
Ich empfehle
setTimeout()
KEINEN Hack, da dies die Leistung verlangsamt! Stattdessen können Sie DOM-Mutationsbeobachter verwenden, um die Änderung der Div-Größe zu verfolgen.JS:
HTML:
Hier ist die Geige
Versuchen Sie, die Div-Größe zu ändern.
Sie können Ihre Methode weiter in die
debounce
Methode einbinden, um die Effizienz zu verbessern.debounce
löst Ihre Methode alle x Millisekunden aus, anstatt jede Millisekunde auszulösen, bei der die Größe des DIV geändert wird.quelle
Die beste Lösung wäre die Verwendung der sogenannten Elementabfragen . Sie sind jedoch nicht Standard, es gibt keine Spezifikation - und die einzige Option besteht darin, eine der verfügbaren Polyfüllungen / Bibliotheken zu verwenden, wenn Sie diesen Weg gehen möchten.
Die Idee hinter Elementabfragen besteht darin, einem bestimmten Container auf der Seite zu ermöglichen, auf den dafür bereitgestellten Speicherplatz zu reagieren. Auf diese Weise können Sie eine Komponente einmal schreiben und dann an einer beliebigen Stelle auf der Seite ablegen, während der Inhalt an die aktuelle Größe angepasst wird. Egal wie groß das Fenster ist. Dies ist der erste Unterschied zwischen Elementabfragen und Medienabfragen. Jeder hofft, dass irgendwann eine Spezifikation erstellt wird, die Elementabfragen (oder etwas, das das gleiche Ziel erreicht) standardisiert und sie nativ, sauber, einfach und robust macht. Die meisten Menschen sind sich einig, dass Medienabfragen sehr begrenzt sind und nicht zu einem modularen Design und einer echten Reaktionsfähigkeit beitragen.
Es gibt einige Polyfills / Bibliotheken, die das Problem auf unterschiedliche Weise lösen (könnte jedoch als Problemumgehung anstelle von Lösungen bezeichnet werden):
Ich habe andere Lösungen für ähnliche Probleme vorgeschlagen. Normalerweise verwenden sie Timer oder die Fenster- / Ansichtsfenstergröße unter der Haube, was keine echte Lösung ist. Darüber hinaus denke ich, dass dies idealerweise hauptsächlich in CSS und nicht in Javascript oder HTML gelöst werden sollte.
quelle
Ich fand, dass diese Bibliothek funktioniert, als MarcJs Lösung nicht:
https://github.com/sdecima/javascript-detect-element-resize
Es ist sehr leicht und erkennt sogar natürliche Größenänderungen über CSS oder einfach das Laden / Rendern von HTML.
Codebeispiel (aus dem Link entnommen):
quelle
Schauen Sie sich diese http://benalman.com/code/projects/jquery-resize/examples/resize/ an.
Es hat verschiedene Beispiele. Versuchen Sie, die Größe Ihres Fensters zu ändern, und sehen Sie, wie Elemente in Containerelementen angepasst werden.
Beispiel mit js Geige, um zu erklären, wie es funktioniert.
Schauen Sie sich diese Geige an http://jsfiddle.net/sgsqJ/4/
In diesem Fall ist resize () an ein Element mit der Klasse "test" sowie an das Fensterobjekt gebunden und beim Resize-Rückruf des Fensterobjekts $ ('. Test') wird resize () aufgerufen.
z.B
quelle
Sie können verwenden
iframe
oderobject
verwendencontentWindow
oder diecontentDocument
Größe ändern. OhnesetInterval
odersetTimeout
Die Schritte:
relative
IFRAME.contentWindow
-onresize
EreignisEin Beispiel für HTML:
Das Javascript:
Laufendes Beispiel
JsFiddle: https://jsfiddle.net/qq8p470d/
Mehr sehen:
element-resize-event
quelle
IFRAME.contentWindow
ist erst verfügbar, wenn dasonload
Ereignis auf dem iframe ausgelöst wird . Möglicherweise möchten Sie auch den Stil hinzufügenvisibility:hidden;
, da der Iframe die Mauseingabe für dahinter stehende Elemente blockieren kann (scheint zumindest im IE "schwebend" zu sein).display
Eigenschaft des Elements zu ändern .Nur das Fensterobjekt generiert ein Ereignis zum Ändern der Größe. Ich weiß nur, wie Sie das tun können, was Sie tun möchten, indem Sie einen Intervall-Timer ausführen, der die Größe regelmäßig überprüft.
quelle
quelle
Erstaunlicherweise so alt wie dieses Problem ist, ist dies in den meisten Browsern immer noch ein Problem.
Wie bereits erwähnt, wird Chrome 64+ jetzt nativ mit Resize Observes ausgeliefert. Die Spezifikation wird jedoch noch optimiert, und Chrome liegt derzeit (Stand: 29.01.2019) hinter der neuesten Ausgabe der Spezifikation .
Ich habe ein paar gute ResizeObserver-Polyfills in freier Wildbahn gesehen, einige folgen jedoch nicht genau der Spezifikation und andere haben einige Berechnungsprobleme.
Ich brauchte dieses Verhalten dringend, um einige reaktionsschnelle Webkomponenten zu erstellen, die in jeder Anwendung verwendet werden können. Damit sie gut funktionieren, müssen sie ihre Abmessungen jederzeit kennen. Daher klang ResizeObservers ideal und ich entschied mich, eine Polyfüllung zu erstellen, die der Spezifikation so genau wie möglich entsprach.
Repo: https://github.com/juggle/resize-observer
Demo: https://codesandbox.io/s/myqzvpmmy9
quelle
Mit Clay.js ( https://github.com/zzarcon/clay ) können Änderungen an der Elementgröße ganz einfach erkannt werden :
quelle
Dieser Blog-Beitrag hat mir geholfen, Größenänderungen an DOM-Elementen effizient zu erkennen.
http://www.backalleycoder.com/2013/03/18/cross-browser-event-based-element-resize-detection/
Wie man diesen Code benutzt ...
Vom Beispiel verwendeter gepackter Code ...
Hinweis: AppConfig ist ein Namespace / Objekt, das ich zum Organisieren wiederverwendbarer Funktionen verwende. Fühlen Sie sich frei, den Namen zu suchen und durch alles zu ersetzen, was Sie möchten.
quelle
Mein jQuery-Plugin aktiviert das Ereignis "Größe ändern" für alle Elemente, nicht nur für das
window
.https://github.com/dustinpoissant/ResizeTriggering
quelle
Sie können den Code im folgenden Snippet ausprobieren. Er deckt Ihre Anforderungen mit einfachem Javascript ab. ( Führen Sie das Code-Snippet aus und klicken Sie auf den Link für die ganze Seite, um die Warnung auszulösen, dass die Größe des Div geändert wird, wenn Sie es testen möchten. )
Sie können die Geige auch überprüfen
AKTUALISIEREN
Geige aktualisiert
quelle
Dies ist so ziemlich eine exakte Kopie der Top-Antwort, aber anstelle eines Links ist es nur der Teil des Codes, der zählt, übersetzt, um IMO besser lesbar und leichter zu verstehen. Einige andere kleine Änderungen umfassen die Verwendung von cloneNode () und das Nicht-Einfügen von HTML in einen js-String. Kleine Sachen, aber Sie können diese kopieren und einfügen, wie es ist, und es wird funktionieren.
Die Funktionsweise besteht darin, dass zwei unsichtbare Divs das gerade angezeigte Element füllen, dann jeweils einen Auslöser einfügen und eine Bildlaufposition festlegen, die bei Änderung der Größe zu einem Bildlaufwechsel führt.
Alle echten Kredite gehen an Marc J, aber wenn Sie nur nach dem relevanten Code suchen, hier ist er:
quelle
Reine Javascript-Lösung, funktioniert aber nur, wenn die Größe des Elements mit der Schaltfläche CSS-Größenänderung geändert wird :
offsetWidth
undoffsetHeight
gespeicherte Werte. Wenn dies nicht der Fall ist, tun Sie, was Sie möchten, und aktualisieren Sie diese Werte.quelle
Hier ist eine vereinfachte Version der Lösung von @nkron, die auf ein einzelnes Element anwendbar ist (anstelle eines Arrays von Elementen in @ nkrons Antwort, Komplexität, die ich nicht brauchte).
Der Ereignis-Listener und -Betrachter kann entfernt werden durch:
quelle
quelle
Wenn Sie die Antwort von Bharat Patil verwenden , geben Sie einfach false in Ihrem Rückruf zurück, um einen maximalen Stapelfehler zu vermeiden. Siehe Beispiel unten:
quelle
Dies ist eine wirklich alte Frage, aber ich dachte, ich würde meine Lösung dazu veröffentlichen.
Ich versuchte es zu benutzen,
ResizeSensor
da jeder ziemlich verknallt zu sein schien. Nach der Implementierung wurde mir jedoch klar, dass die Elementabfrage unter der Haube erfordert, dass das betreffende Element eine Position hatrelative
oder daraufabsolute
angewendet wird, was für meine Situation nicht funktioniert hat.Am Ende habe ich dies mit einem Rxjs
interval
anstatt mit einem StraightsetTimeout
oderrequestAnimationFrame
ähnlichen vorherigen Implementierungen behandelt.Das Schöne an der beobachtbaren Variante eines Intervalls ist, dass Sie den Stream ändern können, jedoch jede andere beobachtbare Funktion verarbeitet werden kann. Für mich war eine grundlegende Implementierung ausreichend, aber Sie könnten verrückt werden und alle möglichen Zusammenführungen usw. durchführen.
Im folgenden Beispiel verfolge ich die Breitenänderungen des inneren (grünen) Div. Es hat eine Breite von 50%, aber eine maximale Breite von 200px. Das Ziehen des Schiebereglers wirkt sich auf die Breite des Wrapper-Divs (grau) aus. Sie können sehen, dass das Observable nur ausgelöst wird, wenn sich die Breite des inneren Divs ändert. Dies geschieht nur, wenn die Breite des äußeren Divs kleiner als 400 Pixel ist.
quelle
Nur
Window.onResize
in der Spezifikation vorhanden, aber Sie können immer verwendenIFrame
, um ein neuesWindow
Objekt in Ihrem DIV zu generieren .Bitte überprüfen Sie diese Antwort . Es gibt ein neues kleines jquery-Plugin , das portabel und einfach zu bedienen ist. Sie können jederzeit den Quellcode überprüfen, um zu sehen, wie es gemacht wird.
quelle
Ich dachte, es könnte nicht gemacht werden, aber dann dachte ich darüber nach, Sie können die Größe eines Div manuell über style = "resize: both;" ändern. Um dies zu tun, müssen Sie darauf klicken. Fügen Sie daher eine On-Click-Funktion hinzu, um die Höhe und Breite des Elements zu überprüfen, und es hat funktioniert. Mit nur 5 Zeilen reinem Javascript (sicher könnte es noch kürzer sein) http://codepen.io/anon/pen/eNyyVN
quelle