簡體   English   中英

在 Internet Explorer 中觸發 window.resize 事件

[英]window.resize event firing in Internet Explorer

如您所知,在 Internet Explorer 中,當頁面上的任何元素調整大小時都會觸發 window.resize 事件。 頁面元素是否通過分配/更改其高度或樣式屬性、通過簡單地向其添加子元素或其他任何方式來調整大小都無關緊要——即使元素調整大小不會影響視口本身的尺寸。

在我的應用程序中,這會導致令人討厭的遞歸,因為在我的 window.resize 處理程序中,我正在調整一些 <li> 元素的大小,這又會重新觸發 window.resize 等。同樣,這只是 IE 中的一個問題。

有什么方法可以防止 window.resize 在響應頁面上的元素被調整大小時在 IE 中觸發?

我還應該提到我正在使用 jQuery。

我剛剛發現了另一個可能對你有幫助的問題。

我正在使用 jQuery 並且我有 window.resize 事件來調用一個函數,該函數將重新定位附加到正文的 div。

現在,當我設置該附加 div 的 LEFT css 屬性時,window.resize 事件會因為沒有好的原因而觸發。

它導致無限循環,一次又一次地觸發 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()綁定您的調整大小偵聽器,以便它在觸發后自行解除綁定。 然后你可以做任何你想做的事情,只要最后你重新綁定調整大小的監聽器。 我發現最簡單的方法是將調整大小的偵聽器放在一個匿名函數中,如下所示:

var resizeListener = function(){
  $(window).one("resize",function(){ //unbinds itself every time it fires

    //resize things

    setTimeout(resizeListener,100); //rebinds itself after 100ms
  });
}
resizeListener();

從技術上講,您不需要將setTimeout包裹在resizeListener()周圍,​​但我將它放在那里作為以防萬一和一些額外的限制。

我通過取消綁定調整大小函數,重建頁面,然后再次綁定調整大小函數來解決它:

function rebuild() {
   $(window).unbind('resize');
   /* do stuff here */
   $(window).bind('resize',rebuild);
}

$(window).bind('resize',rebuild);

編輯

綁定和解除綁定不適用於 IE8。 雖然微軟甚至放棄了 IE8,但你可能想試試這個(未經測試!):

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

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;

一些功能:

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

我今天遇到了這個問題,並決定將以下內容放在我的全局包含的 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;
});

順便說一下,這需要原型。

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

以下是我如何確定 resize 事件是由元素觸發還是通過真正調整窗口大小來處理:

如果事件的 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
    }
});

當元素調整大小時,我無法觸發調整大小事件(盡管僅在 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 事件中的內容。

我發現只有當頁面由靜態內容組成時才能解決上述問題,而不是動態呈現的內容。 在現有內容將被某些觸發事件(如內容重新加載函數)重新渲染的動態情況下,我們需要使用 $(document).width() 或 $(document).height() 代替。

這是因為窗口的滾動條。 如果頁面有滾動條並且主要內容將通過單擊“重新加載”按鈕重新呈現,則滾動條在事件上消失。 在這種情況下, $(window).width() 或 $(window).height() 是由內容呈現改變的,而不是由實際的窗口調整大小改變的。

http://www.tech-step.net/?p=466

$(window).resize(function(event)
{
    if (typeof event.target.tagName == 'undefined')
    {
        // ...
    }
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM