Jak wywołać zdarzenie zmiany rozmiaru okna w JavaScript?

327

Zarejestrowałem wyzwalacz przy zmianie rozmiaru okna. Chcę wiedzieć, jak mogę wywołać zdarzenie, które ma zostać wywołane. Na przykład, gdy ukrywa div, chcę, aby moja funkcja wyzwalacza została wywołana.

Znalazłem, że window.resizeTo()może uruchomić tę funkcję, ale czy jest jakieś inne rozwiązanie?

zhongshu
źródło

Odpowiedzi:

381

Tam, gdzie to możliwe, wolę wywołać funkcję niż wywołać zdarzenie. Działa to dobrze, jeśli masz kontrolę nad kodem, który chcesz uruchomić, ale poniżej znajdziesz przypadki, w których nie masz kodu.

window.onresize = doALoadOfStuff;

function doALoadOfStuff() {
    //do a load of stuff
}

W tym przykładzie możesz wywołać doALoadOfStufffunkcję bez wywoływania zdarzenia.

W nowoczesnych przeglądarkach możesz wywołać zdarzenie, używając:

window.dispatchEvent(new Event('resize'));

To nie działa w Internet Explorerze, gdzie będziesz musiał zrobić długą rękę:

var resizeEvent = window.document.createEvent('UIEvents'); 
resizeEvent.initUIEvent('resize', true, false, window, 0); 
window.dispatchEvent(resizeEvent);

jQuery ma triggermetodę , która działa w następujący sposób:

$(window).trigger('resize');

I ma zastrzeżenie:

Chociaż .trigger () symuluje aktywację zdarzenia wraz ze zsyntetyzowanym obiektem zdarzenia, nie doskonale replikuje naturalnie występującego zdarzenia.

Możesz także symulować zdarzenia dotyczące określonego elementu ...

function simulateClick(id) {
  var event = new MouseEvent('click', {
    'view': window,
    'bubbles': true,
    'cancelable': true
  });

  var elem = document.getElementById(id); 

  return elem.dispatchEvent(event);
}
Fenton
źródło
6
Twoja anonimowa funkcja jest niepotrzebna. window.onresize = doALoadOfStuff; Ponadto, to nie odpowiada na pytanie, odpowiedź pinouchon poniżej jest poprawną odpowiedzią.
Dennis Plucinik,
42
Do Google r: spójrz na odpowiedź @ avetisk.
Fabian Lauer
1
Dobrym pomysłem jest odsprzęgnięcie, ale w moim / tym przypadku to nie działa. Samo wywołanie metody zmiany rozmiaru nie działa, ponieważ jeśli zmiana rozmiaru okna nie zostanie uruchomiona, różne inne div / kontenery nie będą miały ustawionej właściwej wysokości.
PandaWood,
@PandaWood - wtedy mój ostatni przykład jest lepszy w twoim przypadku.
Fenton
Dziękuję @ user75525
Bondsmith
676
window.dispatchEvent(new Event('resize'));
avetisk
źródło
11
wydaje się działać z Chrome, FF, Safari, ale nie: IE!
Davem M
14
jQuery's triggernie wyzwala natywnego zdarzenia „resize”. Uruchamia tylko detektory zdarzeń, które zostały dodane przy użyciu jQuery. W moim przypadku biblioteka innej firmy nasłuchiwała bezpośrednio natywnego zdarzenia „zmiany rozmiaru” i to rozwiązanie działało dla mnie.
chowey
2
Świetne i proste rozwiązanie. Chociaż myślę, że powinieneś dodać trochę kodu dla kompatybilności z IE (o ile widzę, dla IE musimy użyć window.fireEvent)
Victor
35
to nie działało na wszystkich urządzeniach. musiałem wywołać zdarzenie w następujący sposób: var evt = document.createEvent ('UIEvents'); evt.initUIEvent ('resize', true, false, window, 0); window.dispatchEvent (evt);
Manfred
19
Nie działa z „Obiekt nie obsługuje tej akcji” w moim IE11
pomber
156

Za pomocą jQuery możesz spróbować wywołać wyzwalacz :

$(window).trigger('resize');
Benjamin Crouzier
źródło
3
Przykładem tego jest wtyczka jQuery, która reaguje na zdarzenia zmiany rozmiaru okna, ale masz zwinięty pasek boczny. Rozmiar kontenera wtyczki zmienia się, ale okno nie.
isherwood
4
Rzeczywiście nie potrzebujesz JQuery, ale wolę rozwiązanie JQuery, ponieważ mój produkt intensywnie korzysta z JQuery.
Sri
Gdzie można to dodać, aby zmienić rozmiar strony wordpress po jej załadowaniu?
SAHM,
To nie działa dla mnie w najnowszym Chrome, ta odpowiedź działa: stackoverflow.com/a/22638332/1296209
webaholik
1
to jest to, co początkowo wypróbowaną to nie działa, ale window.dispatchEvent(new Event('resize'));nie
user2682863
54

Czysty JS, który działa również w IE (od komentarza @Manfred )

var evt = window.document.createEvent('UIEvents'); 
evt.initUIEvent('resize', true, false, window, 0); 
window.dispatchEvent(evt);

Lub kątowe:

$timeout(function() {
    var evt = $window.document.createEvent('UIEvents'); 
    evt.initUIEvent('resize', true, false, $window, 0); 
    $window.dispatchEvent(evt);
});
pomber
źródło
4
Niestety, dokumentacja dla UIEvent.initUIEvent () mówi, że Do not use this method anymore as it is deprecated.Dokumenty createEvent mówią „Wiele metod używanych z createEvent, takich jak initCustomEvent, jest przestarzałych. Zamiast tego należy używać konstruktorów zdarzeń .” Ta strona wygląda obiecująco na wydarzenia związane z interfejsem użytkownika.
Racing Tadpole,
9
To prawda, ale IE11 nie obsługuje tej new Event()metody. Myślę, że jako hack na starszych przeglądarkach możesz zrobić coś takiego if (Event.prototype.initEvent) { /* deprecated method */ } else { /* current method */ }. Gdzie obecna metoda jest odpowiedzią avetisk .
BrianS,
@pomber Dzięki za rozwiązanie, w rzeczywistości próbowałem uruchomić niestandardowe zdarzenie zmiany rozmiaru okna, aby zmienić rozmiar mojego wykresu ... Twoje rozwiązanie uratuje mój dzień
Dinesh Gopal Chand
49

Łącząc odpowiedzi pomber i avetisk, aby objąć wszystkie przeglądarki i nie powodować ostrzeżeń:

if (typeof(Event) === 'function') {
  // modern browsers
  window.dispatchEvent(new Event('resize'));
} else {
  // for IE and other old browsers
  // causes deprecation warning on modern browsers
  var evt = window.document.createEvent('UIEvents'); 
  evt.initUIEvent('resize', true, false, window, 0); 
  window.dispatchEvent(evt);
}
pfirpfel
źródło
1
Jest to dobry sposób na zrobienie tego w różnych przeglądarkach bez użycia jQuery.
kgx 12.01.2018
nie mam pojęcia, dlaczego nie jest to najlepsza odpowiedź ...... jest lepsza niż odpowiedzi „jedno albo drugie”, które są akceptowane…
SPillai
14

W rzeczywistości nie byłem w stanie zmusić tego do pracy z żadnym z powyższych rozwiązań. Po powiązaniu wydarzenia z jQuery działało dobrze, jak poniżej:

$(window).bind('resize', function () {
    resizeElements();
}).trigger('resize');
BBQ Singular
źródło
Działa dziś w Chrome.
webaholik
9

właśnie

$(window).resize();

to jest to, czego używam ... chyba że źle zrozumiem, o co prosisz.

Matt Sich
źródło
3
Nawet jeśli masz jQuery, wyzwala tylko zdarzenia powiązane z jQuery.
adamdport,
0

Odpowiedź z RxJS

Powiedz jak coś w Angular

size$: Observable<number> = fromEvent(window, 'resize').pipe(
            debounceTime(250),
            throttleTime(300),
            mergeMap(() => of(document.body.clientHeight)),
            distinctUntilChanged(),
            startWith(document.body.clientHeight),
          );

Jeśli wymagana jest subskrypcja ręczna (lub nie kątowa)

this.size$.subscribe((g) => {
      console.log('clientHeight', g);
    })

Ponieważ mój początkowy początek z wartością może być niepoprawny (wysłanie do korekty)

window.dispatchEvent(new Event('resize'));

Mówiąc Angular (mógłbym ...)

<div class="iframe-container"  [style.height.px]="size$ | async" >..
Sergio Wilson
źródło
0

Uważam, że powinno to działać dla wszystkich przeglądarek:

var event;
if (typeof (Event) === 'function') {
    event = new Event('resize');
} else { /*IE*/
    event = document.createEvent('Event');
    event.initEvent('resize', true, true);
}
window.dispatchEvent(event);
webaholik
źródło
Działa świetnie w Chrome i FF, ale nie działał w IE11
Collins
@Collins - dzięki za aktualizację, myślałem, że zweryfikowałem to na IE11 ... Postaram się trochę później zaktualizować, dzięki za opinie.
webaholik
0

Możesz to zrobić za pomocą tej biblioteki. https://github.com/itmor/events-js

const events = new Events();

events.add({  
  blockIsHidden: () =>  {
    if ($('div').css('display') === 'none') return true;
  }
});

function printText () {
  console.log('The block has become hidden!');
}

events.on('blockIsHidden', printText);
To Mor
źródło
-3

window.resizeBy()wywoła zdarzenie onresize okna. Działa to zarówno w JavaScript, jak i VBScript .

window.resizeBy(xDelta, yDelta)nazywa się jak window.resizeBy(-200, -200)zmniejszyć stronę 200 na 200 pikseli.

DO
źródło
2
Dlaczego to jest zaznaczone? Czy to nieprawda? Czy to zależy od przeglądarki?
Peter Wone
2
To nie działa w żadnej przeglądarce: przetestowano Chrome, Firefox, IE, Firefox.
fregante
1
Firefox 7+ i prawdopodobnie inne nowoczesne przeglądarki nie pozwalają już na wywoływanie tej metody w większości przypadków. Ponadto nie jest pożądane, aby faktycznie zmieniać rozmiar okna w celu wyzwolenia zdarzenia.
user247702,
Zarówno resizeBy (), jak i resizeTo () działają dobrze w najnowszej stabilnej wersji Chrome. 76,0
VanagaS,