Как я могу подключиться к событию изменения размера окна браузера?
Существует способ прослушивания событий изменения размера в jQuery, но я бы предпочел не включать его в свой проект только по одному этому требованию.
Как я могу подключиться к событию изменения размера окна браузера?
Существует способ прослушивания событий изменения размера в jQuery, но я бы предпочел не включать его в свой проект только по одному этому требованию.
Ответы:
JQuery просто оборачивает стандартное resize
событие DOM, например.
window.onresize = function(event) {
...
};
jQuery может сделать некоторую работу, чтобы гарантировать, что событие resize будет срабатывать согласованно во всех браузерах, но я не уверен, отличается ли какой-либо из браузеров, но я бы посоветовал вам протестировать в Firefox, Safari и IE.
window.addEventListener('resize', function(){}, true);
window.onresize = () => { /* code */ };
или лучше:window.addEventListener('resize', () => { /* code */ });
Во-первых, я знаю, что addEventListener
метод был упомянут в комментариях выше, но я не видел никакого кода. Поскольку это предпочтительный подход, вот он:
window.addEventListener('resize', function(event){
// do stuff here
});
removeEventListener
.
Никогда не отменяйте функцию window.onresize.
Вместо этого создайте функцию для добавления прослушивателя событий к объекту или элементу. Это проверяет, что слушатели не работают, а затем переопределяет функцию объекта как последнее средство. Это предпочтительный метод, используемый в библиотеках, таких как jQuery.
object
: элемент или оконный объект
type
: изменить размер, прокрутить (тип события)
callback
: ссылка на функцию
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;
}
};
Тогда используйте это так:
addEvent(window, "resize", function_reference);
или с анонимной функцией:
addEvent(window, "resize", function(event) {
console.log('resized');
});
attachEvent
больше не поддерживается. Предпочтительный путь на будущее addEventListener
.
elem == undefined
. Возможно (хотя и маловероятно), что «неопределенный» локально определяется как что-то еще. stackoverflow.com/questions/8175673/…
Событие resize никогда не должно использоваться напрямую, так как оно запускается непрерывно при изменении размера.
Используйте функцию debounce для смягчения лишних вызовов.
window.addEventListener('resize',debounce(handler, delay, immediate),false);
Вот распространенный дебат, распространяющийся по сети, хотя более продвинутые ищите, как featuerd в 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);
};
};
Это можно использовать как так ...
window.addEventListener('resize', debounce(() => console.log('hello'),
200, false), false);
Он никогда не будет срабатывать чаще, чем раз в 200 мс.
Для мобильных изменений ориентации используйте:
window.addEventListener('orientationchange', () => console.log('hello'), false);
Вот небольшая библиотека, которую я собрал, чтобы аккуратно позаботиться об этом.
(...arguments) => {...}
(или ...args
для меньшего количества путаницы), поскольку arguments
переменная больше не доступна в своей области видимости.
Решение для 2018+:
Вы должны использовать ResizeObserver . Это нативное решение для браузера, которое имеет гораздо лучшую производительность, чем использование resize
события. Кроме того, он поддерживает не только событие, document
но и произвольное 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);
В настоящее время Firefox, Chrome и Safari поддерживают его . Для других (и более старых) браузеров вы должны использовать полифилл .
Я верю, что @Alex V уже предоставил правильный ответ, но ответ требует некоторой модернизации, так как ему уже более пяти лет.
Есть два основных вопроса:
Никогда не используйте object
в качестве имени параметра. Это зарезервированное слово. С учетом вышесказанного, функция @Alex V не будет работать в strict mode
.
addEvent
Функция , обеспечиваемая @Alex V не возвращают , event object
если addEventListener
используется метод. Для этого необходимо добавить еще один параметр addEvent
.
ПРИМЕЧАНИЕ. Новый параметр to addEvent
был сделан необязательным, поэтому переход на эту новую версию функции не прервет все предыдущие вызовы этой функции. Все устаревшие варианты использования будут поддерживаться.
Вот обновленная addEvent
функция с этими изменениями:
/*
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;
};
Пример вызова новой addEvent
функции:
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);
Спасибо за ссылку на мой пост в блоге на http://mbccs.blogspot.com/2007/11/fixing-window-resize-event-in-ie.html .
Хотя вы можете просто подключиться к стандартному событию изменения размера окна, вы обнаружите, что в IE событие запускается один раз для каждого X и один раз для каждого движения оси Y, что приводит к возникновению тонны событий, которые могут иметь производительность влияние на ваш сайт, если рендеринг является интенсивной задачей.
Мой метод включает в себя короткий тайм-аут, который отменяется при последующих событиях, чтобы событие не попадало в ваш код, пока пользователь не завершил изменение размера окна.
window.onresize = function() {
// your code
};
Следующее сообщение в блоге может быть полезно для вас: Исправление события изменения размера окна в IE
Он предоставляет этот код:
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); }
Уже упомянутые выше решения будут работать, если все, что вы хотите сделать, это изменить размер окна и только окна. Однако, если вы хотите, чтобы изменение размера распространялось на дочерние элементы, вам нужно будет распространить событие самостоятельно. Вот пример кода для этого:
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);
});
Обратите внимание, что дочерний элемент может вызывать
event.preventDefault();
на объекте события, который передается в качестве первого Arg события resize. Например:
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_];
}
}
}