Mam następujący przykładowy html, jest DIV, który ma 100% szerokości. Zawiera niektóre elementy. Podczas zmiany rozmiaru okien elementy wewnętrzne mogą zostać ponownie ustawione, a wymiar div może się zmienić. Pytam, czy można podpiąć zdarzenie zmiany wymiaru div? i jak to zrobić? Obecnie wiążę funkcję zwrotną ze zdarzeniem zmiany rozmiaru jQuery na docelowym DIV, jednak nie jest generowany dziennik konsoli, patrz poniżej:
<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
źródło
źródło
setInterval
tutaj jako możliwego rozwiązania. Zawsze możesz powiązaćclearInterval
kliknięcie przycisku, aby zatrzymać pętlę po zakończeniu pracy.Odpowiedzi:
Istnieje bardzo skuteczna metoda określania, czy rozmiar elementu został zmieniony.
http://marcj.github.io/css-element-queries/
Ta biblioteka ma klasę,
ResizeSensor
której można użyć do wykrywania zmiany rozmiaru.Wykorzystuje podejście oparte na zdarzeniach, więc jest cholernie szybkie i nie marnuje czasu procesora.
Przykład:
Nie używaj wtyczki jQuery onresize, ponieważ używa ona
setTimeout()
w połączeniu z odczytem DOMclientHeight
/clientWidth
właściwości w pętli w celu sprawdzenia zmian.Jest to niesamowicie wolne i niedokładne, ponieważ powoduje przeładowanie układu .
Ujawnienie: Jestem bezpośrednio powiązany z tą biblioteką.
źródło
requestAnimationFrame
vs niesetTimeout
ma znaczenia, ta biblioteka nie zapętla się .requestAnimationFrame
służy tylko do zmniejszania częstotliwości wywołań wywołań zwrotnych, nie odpytuje . MutationObserver można teoretycznie wykorzystać do podobnego efektu, ale nie w starszych przeglądarkach, w przeciwieństwie do tego. Jest to wyjątkowo sprytne.Nowy standard to Resi Observer api, dostępny w Chrome 64.
Zmień rozmiar obserwatora
Spec: https://wicg.github.io/ResizeObserver
Polyfills: https://github.com/WICG/ResizeObserver/issues/3
Problem z Firefoksem: https://bugzil.la/1272409
Wydanie Safari: http://wkb.ug/157743
Bieżące wsparcie: http://caniuse.com/#feat=resizeobserver
źródło
Musisz powiązać
resize
zdarzenie zwindow
obiektem, a nie z ogólnym elementem HTML.Możesz wtedy użyć tego:
a w ramach funkcji oddzwaniania możesz sprawdzić nową szerokość swojego
div
połączeniaTak więc odpowiedź na twoje pytanie brzmi: nie , nie możesz
resize
przypisać wydarzenia do div.źródło
W dłuższej perspektywie będziesz mógł korzystać z ResizeObserver .
Niestety nie jest obecnie domyślnie obsługiwany w wielu przeglądarkach.
W międzyczasie możesz użyć funkcji takiej jak poniżej. Ponieważ większość zmian rozmiaru elementu będzie pochodzić ze zmiany rozmiaru okna lub zmiany czegoś w DOM. Możesz słuchać zmiany rozmiaru okna za pomocą zdarzenia zmiany rozmiaru okna i możesz słuchać zmian DOM za pomocą MutationObserver .
Oto przykład funkcji, która oddzwoni, gdy rozmiar podanego elementu zmieni się w wyniku jednego z tych zdarzeń:
źródło
body
jak w tym przykładzie, możesz obejrzeć element bezpośrednio. To jest faktycznie bardziej wydajne i wydajne niż obserwowanie całego ciała.ResizeSensor.js jest częścią ogromnej biblioteki, ale ograniczyłem jej funkcjonalność do TEGO :
Jak tego użyć:
źródło
parseInt( getComputedStyle(element) )
NIE polecam
setTimeout()
hackowania, ponieważ spowalnia działanie! Zamiast tego można użyć obserwatorów mutacji DOM do nasłuchiwania zmiany rozmiaru Div.JS:
HTML:
Oto skrzypce
Spróbuj zmienić rozmiar div.
Możesz dodatkowo zawinąć swoją metodę w
debounce
celu poprawy wydajności.debounce
uruchomi twoją metodę co x milisekund zamiast wyzwalać każdą milisekundę zmiany rozmiaru DIV.źródło
Najlepszym rozwiązaniem byłoby użycie tak zwanych zapytań o elementy . Nie są one jednak standardowe, nie istnieje żadna specyfikacja - a jedyną opcją jest użycie jednej z dostępnych wielopełniaczy / bibliotek, jeśli chcesz iść tą drogą.
Ideą zapytań o elementy jest umożliwienie określonego kontenera na stronie odpowiedzi na miejsce, które jest do niego przewidziane. Umożliwi to jednokrotne napisanie komponentu, a następnie upuszczenie go w dowolnym miejscu na stronie, a jednocześnie dostosuje jego zawartość do bieżącego rozmiaru. Bez względu na rozmiar okna. To pierwsza różnica między zapytaniami o elementy a zapytaniami o media. Wszyscy mają nadzieję, że w pewnym momencie zostanie utworzona specyfikacja, która ustandaryzuje zapytania elementów (lub coś, co osiągnie ten sam cel) i sprawi, że będą one rodzime, czyste, proste i niezawodne. Większość ludzi zgadza się, że zapytania o media są dość ograniczone i nie pomagają w budowie modułowej i prawdziwej reakcji.
Istnieje kilka wypełniaczy / bibliotek, które rozwiązują problem na różne sposoby (choć można to nazwać obejściami zamiast rozwiązań):
Widziałem inne rozwiązania podobnych proponowanych problemów. Zwykle używają timerów lub rozmiaru okna / okna pod maską, co nie jest prawdziwym rozwiązaniem. Co więcej, myślę, że najlepiej byłoby to rozwiązać głównie w CSS, a nie w javascript lub HTML.
źródło
Odkryłem, że ta biblioteka działa, gdy rozwiązanie MarcJ nie:
https://github.com/sdecima/javascript-detect-element-resize
Jest bardzo lekki i wykrywa nawet naturalne zmiany rozmiaru za pomocą CSS lub po prostu ładowania / renderowania HTML.
Przykładowy kod (pobrany z linku):
źródło
Spójrz na ten http://benalman.com/code/projects/jquery-resize/examples/resize/
Ma różne przykłady. Spróbuj zmienić rozmiar okna i zobacz, jak dopasowuje się elementy wewnątrz elementów kontenera.
Przykład z skrzypcami js, aby wyjaśnić, jak to działa.
Spójrz na to skrzypce http://jsfiddle.net/sgsqJ/4/
W tym zdarzeniu resize () jest powiązane z elementami posiadającymi klasę „test”, a także z obiektem okna i przy zmianie rozmiaru wywołanie zwrotne obiektu okna $ ('. Test'). Wywoływana jest funkcja resize ().
na przykład
źródło
Możesz użyć
iframe
lubobject
użyćcontentWindow
lubcontentDocument
zmienić rozmiar. BezsetInterval
lubsetTimeout
Kroki:
relative
IFRAME.contentWindow
-onresize
wydarzeniePrzykład HTML:
JavaScript:
Przykład biegania
JsFiddle: https://jsfiddle.net/qq8p470d/
Zobacz więcej:
element-resize-event
źródło
IFRAME.contentWindow
nie jest dostępna, dopókionload
zdarzenie nie zostanie uruchomione w ramce iframe. Możesz także dodać stylvisibility:hidden;
, ponieważ iframe może blokować wejście myszy do elementów znajdujących się za nim (wydaje się, że przynajmniej „unosi się” w IE).display
właściwości elementu nie jest idealna ani wykonalna .Tylko obiekt okna generuje zdarzenie „zmiana rozmiaru”. Jedyny sposób, w jaki wiem, aby robić to, co chcesz, to uruchomić licznik interwałowy, który okresowo sprawdza rozmiar.
źródło
źródło
Zadziwiające, jak stary jest ten problem, jest to nadal problem w większości przeglądarek.
Jak powiedzieli inni, Chrome 64+ jest teraz dostarczany z Resize Observes natywnie, jednak specyfikacja jest nadal dopracowywana, a Chrome jest obecnie (stan na 29.01.2019) za najnowszą edycją specyfikacji .
Widziałem kilka dobrych polifillów ResizeObserver na wolności, jednak niektóre nie są zgodne ze specyfikacją, a inne mają pewne problemy z obliczeniami.
Desperacko potrzebowałem tego zachowania, aby stworzyć responsywne komponenty internetowe, które można by wykorzystać w dowolnej aplikacji. Aby działały ładnie, muszą cały czas znać swoje wymiary, więc ResizeObservers brzmiało idealnie i postanowiłem stworzyć polifill, który byłby zgodny ze specyfikacją tak dokładnie, jak to możliwe.
Repo: https://github.com/juggle/resize-observer
Demo: https://codesandbox.io/s/myqzvpmmy9
źródło
Za pomocą Clay.js ( https://github.com/zzarcon/clay ) dość łatwo jest wykryć zmiany wielkości elementu:
źródło
Ten post na blogu pomógł mi skutecznie wykryć zmiany rozmiaru elementów DOM.
http://www.backalleycoder.com/2013/03/18/cross-browser-event-based-element-resize-detection/
Jak korzystać z tego kodu ...
Kod spakowany użyty w przykładzie ...
Uwaga: AppConfig to przestrzeń nazw / obiekt, którego używam do organizowania funkcji wielokrotnego użytku. Wyszukaj i zastąp nazwę dowolną nazwą.
źródło
Moja wtyczka jQuery umożliwia zdarzenie „zmiana rozmiaru” dla wszystkich elementów, nie tylko
window
.https://github.com/dustinpoissant/ResizeTriggering
źródło
Możesz wypróbować kod z poniższego fragmentu, który zaspokoi Twoje potrzeby za pomocą zwykłego javascript. ( uruchom fragment kodu i kliknij link do pełnej strony, aby wyświetlić alert o zmianie rozmiaru div, jeśli chcesz go przetestować ).
Możesz sprawdzić skrzypce także
AKTUALIZACJA
Zaktualizowano skrzypce
źródło
Jest to właściwie dokładna kopia najważniejszej odpowiedzi, ale zamiast linku liczy się tylko część kodu, przetłumaczona na IMO, bardziej czytelna i łatwiejsza do zrozumienia. Kilka innych drobnych zmian obejmuje użycie cloneNode () i niewprowadzanie html do łańcucha js. Małe rzeczy, ale możesz skopiować i wkleić to tak, jak jest i będzie działać.
Jego działanie polega na tym, aby dwa niewidoczne div wypełniały oglądany element, a następnie umieszczając w nich wyzwalacz i ustawiając pozycję przewijania, która spowoduje zmianę przewijania, jeśli zmieni się rozmiar.
Prawdziwe uznanie należy się Marcowi J, ale jeśli szukasz odpowiedniego kodu, oto on:
źródło
Czyste rozwiązanie JavaScript, ale działa tylko wtedy, gdy rozmiar elementu zmienia się za pomocą przycisku zmiany rozmiaru css :
offsetWidth
ioffsetHeight
z zapisanymi wartościami, a jeśli się różnią, to, co chcesz i zaktualizować te wartości.źródło
Oto uproszczona wersja rozwiązania @nkron, mająca zastosowanie do pojedynczego elementu (zamiast tablicy elementów w odpowiedzi @ nkron, złożoność, której nie potrzebowałem).
Detektor i obserwator zdarzeń można usunąć poprzez:
źródło
źródło
używając odpowiedzi Bharat Patil po prostu zwróć false w wywołaniu zwrotnym powiązania, aby uniknąć błędu maksymalnego stosu, patrz przykład poniżej:
źródło
To naprawdę stare pytanie, ale pomyślałem, że opublikuję moje rozwiązanie tego problemu.
Próbowałem użyć,
ResizeSensor
ponieważ wszyscy wydawali się mieć dość dużą sympatię. Po wdrożeniu uświadomiłem sobie, że pod maską element zapytania wymaga, aby dany element miał pozycjęrelative
lubabsolute
zastosował się do niego, co nie działało w mojej sytuacji.Skończyło się to na Rxjs
interval
zamiast na prostychsetTimeout
lubrequestAnimationFrame
podobnych wcześniejszych implementacjach.Co jest miłego w obserwowalnym smaku interwału, to fakt, że możesz zmodyfikować strumień, jednak każdy inny obserwowalny może być obsługiwany. Dla mnie wystarczyła podstawowa implementacja, ale można było zwariować i wykonywać różnego rodzaju scalenia itp.
W poniższym przykładzie śledzę zmiany szerokości wewnętrznej div (zielonej). Ma szerokość ustawioną na 50%, ale maksymalną szerokość 200 pikseli. Przeciągnięcie suwaka wpływa na szerokość otoku otoki (szary). Widać, że obserwowalny jest uruchamiany tylko wtedy, gdy zmienia się szerokość wewnętrznego div, co dzieje się tylko wtedy, gdy szerokość div zewnętrznego jest mniejsza niż 400 pikseli.
źródło
Window.onResize
Istnieje tylko w specyfikacji, ale zawsze możesz użyćIFrame
do wygenerowania nowegoWindow
obiektu w swoim DIV.Sprawdź tę odpowiedź . Nowa mała wtyczka jquery jest przenośna i łatwa w użyciu. Zawsze możesz sprawdzić kod źródłowy, aby zobaczyć, jak to się robi.
źródło
myślałem, że nie da się tego zrobić, ale potem pomyślałem o tym, możesz ręcznie zmienić rozmiar div za pomocą style = "resize: zarówno;" aby to zrobić, kliknij go, więc dodałeś funkcję onclick, aby sprawdzić wysokość i szerokość elementu i zadziałało. Tylko 5 linii czystego javascript (na pewno może być nawet krótszy) http://codepen.io/anon/pen/eNyyVN
źródło