JavaScript窗口大小调整事件

我怎样才能钩入浏览器窗口resize事件?

有一种监听resize事件的jQuery方法,但是我不希望将这个方法带入我的项目中。

jQuery只是包装标准的resize DOM事件,例如。

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

jQuery 可能会做一些工作以确保resize事件在所有浏览器中一致地被触发,但是我不确定是否有任何浏览器有所不同,但是我build议您在Firefox,Safari和IE中进行testing。

切勿覆盖window.onresize函数。

相反,创build一个函数来将Event Listener添加到对象或元素。 这将检查并避免侦听器不工作,那么它将覆盖对象的函数作为最后的手段。 这是在jQuery等库中使用的首选方法。

object :元素或窗口对象
type :resize,scroll(事件types)
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); 

或者使用匿名function:

 addEvent(window, "resize", function(event) { console.log('resized'); }); 

首先,我知道上面的注释中已经提到了addEventListener方法,但是我没有看到任何代码。 由于这是首选方法,因此它是:

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

这是一个工作示例 。

感谢您在http://mbccs.blogspot.com/2007/11/fixing-window-resize-event-in-ie.html上引用我的博客文章。;

虽然你可以连接到标准的窗口大小事件,你会发现,在IE浏览器中,每发生一次X事件,每发生一次Y轴事件都会触发事件,导致大量的事件被触发,如果渲染是一项密集型任务,则会影响您的网站。

我的方法涉及一个短暂的超时,在随后的事件中取消,这样事件不会冒泡到您的代码,直到用户完成窗口的大小调整。

我确实相信@Alex V已经提供了正确的答案,但是现在的答案确实需要一些现代化。

有两个主要问题:

  1. 永远不要使用object作为参数名称。 这是一个储备的词。 有了这个说法,@Alex V提供的function将不能在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); 
 window.onresize = function() { // your code }; 

resize事件不应该被直接使用,因为它会在我们resize时被连续触发。

使用去抖function来减轻多余的呼叫。

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

这里有一个常见的反弹动作,尽pipe在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); 

这里有一个小型的图书馆,我把它放在一起照顾整齐。

以下博客文章可能对您有用: 在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); } 
 <script language="javascript"> window.onresize = function() { document.getElementById('ctl00_ContentPlaceHolder1_Accordion1').style.height = '100%'; } </script> 

上面已经提到的解决scheme将工作,如果你只想调整窗口和窗口的大小。 但是,如果要将resize传播到子元素,则需要自行传播事件。 以下是一些示例代码:

 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_]; } } }