web-dev-qa-db-fra.com

déclenchement de l'événement window.resize dans Internet Explorer

Comme vous le savez, dans Internet Explorer, l'événement window.resize est déclenché lorsqu'un élément de la page est redimensionné. Peu importe que l'élément de page soit redimensionné en affectant/modifiant sa hauteur ou son style , simplement en y ajoutant un élément enfant, ou autre chose - même si le redimensionnement de l'élément n'affecte pas les dimensions de la fenêtre elle-même.

Dans mon application, cela provoque une récursivité désagréable, car dans mon gestionnaire window.resize je redimensionne certains éléments <li>, qui à leur tour relancent window.resize, etc. Encore une fois, ce n'est qu'un problème dans IE.

Existe-t-il un moyen de empêcher window.resize de se déclencher IE en réponse aux éléments de la page en cours de redimensionnement?

Je dois également mentionner que j'utilise jQuery.

75
MissingLinq

Je viens de découvrir un autre problème qui pourrait vous aider.

J'utilise jQuery et j'ai un événement window.resize pour appeler une fonction qui repositionnera le div ajouté au corps.

Maintenant, lorsque j'ai défini la propriété css LEFT de ce div ajouté, l'événement window.resize est déclenché pour NO GOOD REASON.

Il en résulte une boucle infinie, déclenchant le window.resize encore et encore.

Le code sans correctif:

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

Solution:

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

Donc, fondamentalement, il vérifiera si la hauteur ou la largeur est modifiée (ce qui se produira UNIQUEMENT lorsque vous redimensionnez réellement avec la fenêtre).

58
Aamir Afridi

cela avait du sens pour moi et semble fonctionner dans IE7 et au-dessus:

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


        }
    });
25
Sabrina Leggett

Liez votre écouteur de redimensionnement avec .one() afin qu'il se délie après le tir. Ensuite, vous pouvez faire tout ce que vous voulez, à la fin, à la fin, vous liez à nouveau l'écouteur de redimensionnement. J'ai trouvé le moyen le plus simple de le faire en plaçant l'écouteur de redimensionnement dans une fonction anonyme comme ceci:

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

    //resize things

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

Techniquement, vous n'avez pas besoin du setTimeout enroulé autour de la resizeListener() mais je l'ai jeté dedans juste au cas où et pour un étranglement supplémentaire.

18
brentonstrine

Je l'ai résolu en dissociant la fonction de redimensionnement, en reconstruisant la page, puis en reliant à nouveau la fonction de redimensionnement:

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

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

MODIFIER

Lier et délier ne va pas bien avec IE8. Bien que Microsoft ait même abandonné IE8, vous voudrez peut-être essayer ceci (non testé!):

function rebuild(){
   if(!window.resizing) return false;
   window.resizing=true;
   /* do stuff here */
   window.resizing=false;
}

window.resizing=false;
document.body.onresize=rebuild;
5
patrick

La réponse de @ AamirAfridi.com a résolu mon problème.

C'est une bonne idée d'écrire une fonction commune pour résoudre ce genre de choses:

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

Utilisez-le comme ceci, et vous n'avez plus à vous soucier du comportement différent dans IE plus:

onWindowResize(function() {
    // do something
});
4
Dong

Vous pouvez essayer ceci:

Constructeur:

this.clientWidth = null;
this.clientHeight = null;

Certaines fonctions:

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 ...
} 

Pour Internet Explorer, Chrome, Firefox, Opera et Safari:

window.innerHeight - the inner height of the browser window
window.innerWidth - the inner width of the browser window

Pour Internet Explorer 8, 7, 6, 5:

document.documentElement.clientHeight
document.documentElement.clientWidth
    or
document.body.clientHeight
document.body.clientWidth
1
1ubos

Un mélange de la méthode unbind/bind avec un appel retardé. Il fonctionne dans Internet Explorer 8 et versions ultérieures, empêchant les boucles malveillantes et se bloque sur les versions 6 et 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 );
1
Raohmaru

J'ai rencontré ce problème aujourd'hui et j'ai décidé de mettre ce qui suit en haut de mon fichier javascript global inclus:

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

Cela nécessite d'ailleurs un prototype.

1
Nick
<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++);
}
0
Ascis

Voici comment je traite pour savoir si l'événement de redimensionnement a été déclenché par un élément ou en redimensionnant vraiment la fenêtre:

Si le target.nodeType de l'événement n'existe pas, il s'agit très probablement de la fenêtre, car tout autre élément de la page aurait un nodeType.

Voici donc le pseudo-code (en utilisant jQuery) avec la vérification ajoutée:

$(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
    }
});
0
zıəs uɐɟəʇs
(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;
     });
})();

fait l'affaire pour moi ...

0
David Moldenhauer