在Internet Explorer中触发window.resize事件
如您所知,在Internet Explorer中, window.resize事件在页面上的任何元素被resize时触发。 通过分配/改变其高度或样式属性,通过简单地添加一个子元素,或者其他 – 即使元素resize不影响视口本身的尺寸,页面元素是否被resize并不重要。
在我的应用程序中,这是一个令人讨厌的recursion,因为在我的window.resize处理程序中,我调整了一些<li>元素,这又重新激发了window.resize等等。再次,这只是IE中的一个问题。
有没有什么办法来防止window.resize在IE浏览器响应被调整页面上的元素?
我还应该提到我正在使用jQuery。
我刚刚发现了另一个可能帮助你的问题。
我正在使用jQuery,我有window.resize事件来调用一个函数,将重新定位附加到正文的div。
现在,当我设置该附加div的LEFT css属性时,window.resize事件触发NO GOOD REASON。
它导致无限循环,一次又一次地触发window.resize。
代码没有修复:
$(window).resize(function(){ var onResize = function(){ //The method which alter some css properties triggers //window.resize again and it ends in an infinite loop someMethod(); } window.clearTimeout(resizeTimeout); resizeTimeout = window.setTimeout(onResize, 10); });
解:
var winWidth = $(window).width(), winHeight = $(window).height(); $(window).resize(function(){ var onResize = function(){ //The method which alter some css properties triggers //window.resize again and it ends in an infinite loop someMethod(); } //New height and width var winNewWidth = $(window).width(), winNewHeight = $(window).height(); // compare the new height and width with old one if(winWidth!=winNewWidth || winHeight!=winNewHeight){ window.clearTimeout(resizeTimeout); resizeTimeout = window.setTimeout(onResize, 10); } //Update the width and height winWidth = winNewWidth; winHeight = winNewHeight; });
所以基本上它会检查高度或宽度是否改变(只有当你实际调整窗口大小时才会发生这种情况)。
这对我来说是有意义的,似乎在IE7和以上的工作:
//variables to confirm window height and width var lastWindowHeight = $(window).height(); var lastWindowWidth = $(window).width(); $(window).resize(function() { //confirm window was actually resized if($(window).height()!=lastWindowHeight || $(window).width()!=lastWindowWidth){ //set this windows size lastWindowHeight = $(window).height(); lastWindowWidth = $(window).width(); //call my function myfunction(); } });
使用.one()
绑定您的resize的侦听器,以便在发射后解除绑定。 那么你可以做任何你想要的,只要最后你重新resize的听众。 我发现最简单的方法是将大小监听器放在一个匿名函数中,如下所示:
var resizeListener = function(){ $(window).one("resize",function(){ //unbinds itself every time it fires //resize things setTimeout(resizeListener,100); //rebinds itself after 100ms }); } resizeListener();
你在技术上并不需要在resizeListener()
周围包装setTimeout
但是我把它作为一个大小写的东西扔在那里,还有一些额外的限制。
我通过解除resize函数,重新构build页面,然后再次绑定resize函数来解决它:
function rebuild() { $(window).unbind('resize'); /* do stuff here */ $(window).bind('resize',rebuild); } $(window).bind('resize',rebuild);
编辑
绑定和解绑与IE8不兼容。 虽然微软甚至放弃了IE8,但你可能想试试这个(未经testing!):
function rebuild(){ if(!window.resizing) return false; window.resizing=true; /* do stuff here */ window.resizing=false; } window.resizing=false; document.body.onresize=rebuild;
@AamirAfridi.com的答案解决了我的问题。
编写一个通用的函数来解决这样的问题是个好主意:
function onWindowResize(callback) { var width = $(window).width(), height = $(window).height(); $(window).resize(function() { var newWidth = $(window).width(), newHeight = $(window).height(); if (newWidth !== width || newHeight !== height) { width = newWidth; height = newHeight; callback(); } }); }
像这样使用它,你不必担心IE中的不同行为:
onWindowResize(function() { // do something });
我今天遇到这个问题,并决定把以下放在我的全球包括JavaScript文件的顶部:
var savedHeight = 0; var savedWidth = 0; Event.observe(window, 'resize', function (e) { if (window.innerHeight == savedHeight && window.innerWidth == savedWidth) { e.stop(); } savedHeight = window.innerHeight; savedWidth = window.innerWidth; });
顺便说一下,这需要Prototype。
unbind
/ bind
方法与延迟调用的混合。 它可以在Internet Explorer 8及以下版本中使用,防止恶意循环并在版本6和7上挂起。
function resizeViewport() { // Unbind and rebind only for IE < 9 var isOldIE = document.all && !document.getElementsByClassName; if( isOldIE ) $(window).unbind( 'resize', resizeViewport ); // ... if( isOldIE ) { setTimeout(function(){ $(window).resize( resizeViewport ); }, 100); } } $(window).resize( resizeViewport );
你可以试试这个:
构造函数:
this.clientWidth = null; this.clientHeight = null;
一些function:
var clientWidth = window.innerWidth || document.documentElement.clientWidth; var clientHeight = window.innerHeight || document.documentElement.clientHeight; if (clientWidth != this.clientWidth || clientHeight != this.clientHeight ) { this.clientWidth = clientWidth; this.clientHeight = clientHeight; ... YOUR CODE ... }
对于Internet Explorer,Chrome,Firefox,Opera和Safari:
window.innerHeight - the inner height of the browser window window.innerWidth - the inner width of the browser window
对于Internet Explorer 8,7,6,5:
document.documentElement.clientHeight document.documentElement.clientWidth or document.body.clientHeight document.body.clientWidth
(function ($){ //if ie8 -> return; var lastHeight = 0; var lastWidth = 0; $(window).resize(function(event){ if (window.innerHeight == lastHeight && window.innerWidth == lastWidth) { event.stopImmediatePropagation(); } lastHeight = window.innerHeight; lastHeight = window.innerWidth; }); })();
为我做的伎俩…
<pre> var cont = 0; var tmRsize = 100; var lastWindowWidth = $(window).width(); var lastWindowHeight = $(window).height(); /*****redimensionamiento**********/ $(window).resize(function() { if($(window).width() != lastWindowWidth || $(window).height() != lastWindowHeight) { clearTimeout(this.id); this.tiempo = tmRsize; this.id = setTimeout(doResize, this.tiempo); } }); function doResize() { lastWindowWidth = $(window).width(); lastWindowHeight = $(window).height(); $('#destino_1').html(cont++); }
以下是我如何处理调查大小事件是由一个元素或真正调整窗口的大小:
如果事件的target.nodeType不存在,则很可能是该窗口,因为页面上的任何其他元素都有一个nodeType。
所以这里是添加检查的伪代码(使用jQuery):
$(window).resize(function(event){ if ( $(event.target.nodeType).length == 0 ){ // Anything here is run when the window was resized // not executed when an element triggered the resize } });
当调整元素的大小时,我无法触发resize事件(只能在IE8中尝试)。
然而,当你遇到这个问题时事件对象的target
是什么,你可以这样做:
$(window).resize(function(e) { if( e.target != window ) return; // your stuff here });
我的补丁:
<!--[if lte IE 7]> <script type="text/javascript"> window.onresize = null; // patch to prevent infinite loop in IE6 and IE7 </script> <![endif]-->
这取决于resize事件的内容。
只有当页面由静态内容组成时,我才想出了上述解决scheme,而不是dynamic呈现的内容。 在dynamic的情况下,现有的内容将通过内容重载function等触发事件重新渲染,我们需要使用$(document).width()或$(document).height()。
这是因为窗口的滚动条。 如果页面有滚动条,主要内容将通过点击“重新加载”button重新呈现,则滚动条在事件中消失。 在这种情况下,$(window).width()或$(window).height()被内容渲染改变,而不是被实际的窗口大小调整。
$(window).resize(function(event) { if (typeof event.target.tagName == 'undefined') { // ... } });