JavaScript窗口调整大小事件

如何连接到浏览器窗口调整大小事件?

监听调整大小事件的jQuery方式,但我宁愿不把它带到我的项目中,只为了这一个需求。

1179480 次浏览

最佳做法是添加到resize事件,而不是替换它:

window.addEventListener('resize', function(event) {
...
}, true);

另一种方法是为DOM事件创建一个处理程序(但只能有一个),例如。

window.onresize = function(event) {
...
};

jQuery可能做了一些工作来确保在所有浏览器中一致地触发resize事件,但我不确定是否有任何浏览器不同,但我鼓励您在Firefox,Safari和IE中进行测试。

以下博客文章可能对您有用:修复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.onresize = function() {
// your code
};

永远不要重写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');
});
<script language="javascript">
window.onresize = function() {
document.getElementById('ctl00_ContentPlaceHolder1_Accordion1').style.height = '100%';
}


</script>

首先,我知道addEventListener方法已经在上面的评论中提到,但我没有看到任何代码。由于它是首选方法,因此如下所示:

window.addEventListener('resize', function(event){
// do stuff here
});

这是一个工作样本

如果你只想调整窗口和窗口的大小,上面提到的解决方案将有效。但是,如果你想将调整大小传播到子元素,你需要自己传播事件。这是一些示例代码:

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();

在作为resize事件的第一个Arg传入的事件对象上。例如:

var child1 = document.getElementById("child1");
child1.addEventListener("resize", function (event) {
...
event.preventDefault();
});
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_];
}
}
}

我相信@Alex V已经提供了正确的答案,但答案确实需要一些现代化,因为它现在已经超过五年了。

有两个主要问题:

  1. 永远不要使用object作为参数名。它是一个保留字。话虽如此,@Alex V提供的函数将无法在strict mode中工作。

  2. 如果使用addEventListener方法,@Alex V提供的addEvent函数不会返回event object。应向addEvent函数添加另一个参数以允许此操作。

注意: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);

不应该直接使用resize事件,因为当我们调整大小时,它会连续触发。

使用防抖功能来减轻多余的呼叫。

window.addEventListener('resize',debounce(handler, delay, immediate),false);

这是一个常见的防抖漂浮在网上,尽管要寻找更高级的功能,如豆沙。

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);

它永远不会超过每200ms发射一次。

对于移动方向更改,请使用:

window.addEventListener('orientationchange', () => console.log('hello'), false);

这是一个小型图书馆我放在一起,以整齐地照顾这个。

2018+解决方案:

你应该使用尺寸观察器。它是一种浏览器原生解决方案,比使用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和Edge支持它。对于其他(和更旧的)浏览器,您必须使用聚填充

您可以使用以下方法适合小项目

<body onresize="yourHandler(event)">

function yourHandler(e) {
console.log('Resized:', e.target.innerWidth)
}
<body onresize="yourHandler(event)">
Content... (resize browser to see)
</body>