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