Jak mogę podłączyć zdarzenie zmiany rozmiaru okna przeglądarki?
Istnieje sposób jQuery nasłuchiwania zdarzeń zmiany rozmiaru, ale wolałbym nie włączać go do mojego projektu tylko z tego powodu.
Jak mogę podłączyć zdarzenie zmiany rozmiaru okna przeglądarki?
Istnieje sposób jQuery nasłuchiwania zdarzeń zmiany rozmiaru, ale wolałbym nie włączać go do mojego projektu tylko z tego powodu.
Odpowiedzi:
jQuery właśnie otacza standardowe resize
zdarzenie DOM, np.
window.onresize = function(event) {
...
};
jQuery może trochę popracować, aby zapewnić, że zdarzenie zmiany rozmiaru będzie uruchamiane konsekwentnie we wszystkich przeglądarkach, ale nie jestem pewien, czy którakolwiek z przeglądarek się różni, ale zachęcam do przetestowania w Firefox, Safari i IE.
window.addEventListener('resize', function(){}, true);
window.onresize = () => { /* code */ };
lub lepszy:window.addEventListener('resize', () => { /* code */ });
Po pierwsze, wiem, że addEventListener
metoda została wspomniana w komentarzach powyżej, ale nie widziałem żadnego kodu. Ponieważ jest to preferowane podejście, oto:
window.addEventListener('resize', function(event){
// do stuff here
});
removeEventListener
.
Nigdy nie zastępuj funkcji window.onresize.
Zamiast tego utwórz funkcję, aby dodać detektor zdarzeń do obiektu lub elementu. To sprawdza i powoduje, że detektory nie działają, a następnie zastępuje funkcję obiektu w ostateczności. Jest to preferowana metoda stosowana w bibliotekach takich jak jQuery.
object
: element lub obiekt okna
type
: zmiana rozmiaru, przewijanie (typ zdarzenia)
callback
: odwołanie do funkcji
var addEvent = function(object, type, callback) {
if (object == null || typeof(object) == 'undefined') return;
if (object.addEventListener) {
object.addEventListener(type, callback, false);
} else if (object.attachEvent) {
object.attachEvent("on" + type, callback);
} else {
object["on"+type] = callback;
}
};
Zatem użycie jest takie:
addEvent(window, "resize", function_reference);
lub z anonimową funkcją:
addEvent(window, "resize", function(event) {
console.log('resized');
});
attachEvent
nie jest już obsługiwany. Preferowanym sposobem na przyszłość jest addEventListener
.
elem == undefined
. Możliwe (choć mało prawdopodobne), że „niezdefiniowany” jest lokalnie zdefiniowany jako coś innego. stackoverflow.com/questions/8175673/…
Zdarzenie zmiany rozmiaru nigdy nie powinno być używane bezpośrednio, ponieważ jest uruchamiane w sposób ciągły podczas zmiany rozmiaru.
Użyj funkcji debounce, aby złagodzić nadmiar połączeń.
window.addEventListener('resize',debounce(handler, delay, immediate),false);
Oto powszechna debata unosząca się w sieci, ale szukaj bardziej zaawansowanych, jak featta w lodash.
const debounce = (func, wait, immediate) => {
var timeout;
return () => {
const context = this, args = arguments;
const later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
const callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
Można to wykorzystać tak ...
window.addEventListener('resize', debounce(() => console.log('hello'),
200, false), false);
Nigdy nie będzie strzelał więcej niż raz na 200 ms.
Do zmian orientacji mobilnej użyj:
window.addEventListener('orientationchange', () => console.log('hello'), false);
Oto mała biblioteka, którą stworzyłem, aby starannie się tym zająć.
(...arguments) => {...}
(lub ...args
dla mniejszego zamieszania), ponieważ arguments
zmienna nie jest już dostępna.
Rozwiązanie dla 2018+:
Powinieneś użyć ResizeObserver . Jest to rozwiązanie natywne dla przeglądarki, które ma znacznie lepszą wydajność niż korzystanie ze resize
zdarzenia. Ponadto obsługuje nie tylko zdarzenie, document
ale także arbitralne elements
.
var ro = new ResizeObserver( entries => { for (let entry of entries) { const cr = entry.contentRect; console.log('Element:', entry.target); console.log(`Element size: ${cr.width}px x ${cr.height}px`); console.log(`Element padding: ${cr.top}px ; ${cr.left}px`); } }); // Observe one or multiple elements ro.observe(someElement);
Obecnie obsługują go Firefox, Chrome i Safari . W przypadku innych (i starszych) przeglądarek musisz użyć wypełnienia wypełniającego .
Uważam, że @Alex V udzielił prawidłowej odpowiedzi, ale odpowiedź wymaga pewnej modernizacji, ponieważ ma już ponad pięć lat.
Istnieją dwa główne problemy:
Nigdy nie używaj object
jako nazwy parametru. To słowo zastrzeżone. Biorąc to pod uwagę, zapewniona funkcja @Alex V nie będzie działać strict mode
.
addEvent
Funkcję dostarczaną przez @Alex V nie zwracają event object
jeśli addEventListener
stosowana jest metoda. Aby addEvent
to umożliwić, należy dodać kolejny parametr do funkcji.
UWAGA: Nowy parametr addEvent
został opcjonalny, aby migracja do tej nowej wersji funkcji nie przerywała żadnych wcześniejszych wywołań tej funkcji. Wszystkie starsze zastosowania będą obsługiwane.
Oto zaktualizowana addEvent
funkcja z następującymi zmianami:
/*
function: addEvent
@param: obj (Object)(Required)
- The object which you wish
to attach your event to.
@param: type (String)(Required)
- The type of event you
wish to establish.
@param: callback (Function)(Required)
- The method you wish
to be called by your
event listener.
@param: eventReturn (Boolean)(Optional)
- Whether you want the
event object returned
to your callback method.
*/
var addEvent = function(obj, type, callback, eventReturn)
{
if(obj == null || typeof obj === 'undefined')
return;
if(obj.addEventListener)
obj.addEventListener(type, callback, eventReturn ? true : false);
else if(obj.attachEvent)
obj.attachEvent("on" + type, callback);
else
obj["on" + type] = callback;
};
Przykładowe wywołanie nowej addEvent
funkcji:
var watch = function(evt)
{
/*
Older browser versions may return evt.srcElement
Newer browser versions should return evt.currentTarget
*/
var dimensions = {
height: (evt.srcElement || evt.currentTarget).innerHeight,
width: (evt.srcElement || evt.currentTarget).innerWidth
};
};
addEvent(window, 'resize', watch, true);
Dzięki za odwołanie się do mojego postu na blogu pod adresem http://mbccs.blogspot.com/2007/11/fixing-window-resize-event-in-ie.html .
Chociaż możesz po prostu podłączyć się do standardowego zdarzenia zmiany rozmiaru okna, przekonasz się, że w IE zdarzenie jest uruchamiane raz na każdy ruch X i raz na każdy ruch w osi Y, w wyniku czego wywoływana jest tona zdarzeń, które mogą mieć wydajność wpływ na witrynę, jeśli renderowanie jest intensywnym zadaniem.
Moja metoda polega na krótkim przekroczeniu limitu czasu, który jest anulowany przy kolejnych zdarzeniach, dzięki czemu zdarzenie nie jest propagowane do twojego kodu, dopóki użytkownik nie zmieni rozmiaru okna.
window.onresize = function() {
// your code
};
Przydatny może być następujący post na blogu: Naprawianie zdarzenia zmiany rozmiaru okna w IE
Zapewnia ten kod:
Sys.Application.add_load(function(sender, args) { $addHandler(window, 'resize', window_resize); }); var resizeTimeoutId; function window_resize(e) { window.clearTimeout(resizeTimeoutId); resizeTimeoutId = window.setTimeout('doResizeCode();', 10); }
Wymienione powyżej rozwiązania będą działać, jeśli wszystko, co chcesz zrobić, to zmienić rozmiar okna i tylko okna. Jeśli jednak chcesz, aby zmiana rozmiaru była propagowana do elementów potomnych, musisz sam propagować zdarzenie. Oto przykładowy kod, aby to zrobić:
window.addEventListener("resize", function () {
var recResizeElement = function (root) {
Array.prototype.forEach.call(root.childNodes, function (el) {
var resizeEvent = document.createEvent("HTMLEvents");
resizeEvent.initEvent("resize", false, true);
var propagate = el.dispatchEvent(resizeEvent);
if (propagate)
recResizeElement(el);
});
};
recResizeElement(document.body);
});
Zauważ, że element potomny może wywoływać
event.preventDefault();
na obiekcie zdarzenia, który jest przekazywany jako pierwszy argument zdarzenia zmiany rozmiaru. Na przykład:
var child1 = document.getElementById("child1");
child1.addEventListener("resize", function (event) {
...
event.preventDefault();
});
<script language="javascript">
window.onresize = function() {
document.getElementById('ctl00_ContentPlaceHolder1_Accordion1').style.height = '100%';
}
</script>
var EM = new events_managment();
EM.addEvent(window, 'resize', function(win,doc, event_){
console.log('resized');
//EM.removeEvent(win,doc, event_);
});
function events_managment(){
this.events = {};
this.addEvent = function(node, event_, func){
if(node.addEventListener){
if(event_ in this.events){
node.addEventListener(event_, function(){
func(node, event_);
this.events[event_](win_doc, event_);
}, true);
}else{
node.addEventListener(event_, function(){
func(node, event_);
}, true);
}
this.events[event_] = func;
}else if(node.attachEvent){
var ie_event = 'on' + event_;
if(ie_event in this.events){
node.attachEvent(ie_event, function(){
func(node, ie_event);
this.events[ie_event]();
});
}else{
node.attachEvent(ie_event, function(){
func(node, ie_event);
});
}
this.events[ie_event] = func;
}
}
this.removeEvent = function(node, event_){
if(node.removeEventListener){
node.removeEventListener(event_, this.events[event_], true);
this.events[event_] = null;
delete this.events[event_];
}else if(node.detachEvent){
node.detachEvent(event_, this.events[event_]);
this.events[event_] = null;
delete this.events[event_];
}
}
}