244 votes

JavaScript/JQuery : $(window).resize comment activer APRÈS le redimensionnement ?

J'utilise JQuery comme tel :

$(window).resize(function() { ... });

Cependant, il semble que si la personne redimensionne manuellement la fenêtre de son navigateur en faisant glisser le bord de la fenêtre pour l'agrandir/la réduire, l .resize ci-dessus se déclenche plusieurs fois.

Question : Comment appeler une fonction APRÈS la fin du redimensionnement de la fenêtre du navigateur (pour que l'événement ne se déclenche qu'une seule fois) ?

0 votes

Voir cette réponse : stackoverflow.com/questions/667426/ Elle implique l'utilisation de délais d'attente pour retarder l'exécution de votre fonction.

0 votes

Je ne sais pas si c'est possible, mais vous pouvez essayer ce plugin. benalman.com/projets/jquery-resize-plugin

0 votes

Au fait, j'ai remarqué que cela est très utile dans les navigateurs mobiles qui ont tendance à masquer progressivement la barre d'adresse lorsque l'utilisateur fait défiler l'écran vers le bas, donc le redimensionne. Je m'attendais également à ce que le redimensionnement de l'écran ne se produise que sur le bureau...

308voto

brahn Points 3760

Voici une modification de la solution de CMS qui peut être appelée à plusieurs endroits dans votre code :

var waitForFinalEvent = (function () {
  var timers = {};
  return function (callback, ms, uniqueId) {
    if (!uniqueId) {
      uniqueId = "Don't call this twice without a uniqueId";
    }
    if (timers[uniqueId]) {
      clearTimeout (timers[uniqueId]);
    }
    timers[uniqueId] = setTimeout(callback, ms);
  };
})();

Utilisation :

$(window).resize(function () {
    waitForFinalEvent(function(){
      alert('Resize...');
      //...
    }, 500, "some unique string");
});

La solution de CMS est bonne si vous ne l'appelez qu'une seule fois, mais si vous l'appelez plusieurs fois, par exemple si différentes parties de votre code mettent en place des rappels séparés pour le redimensionnement de la fenêtre, alors elle échouera car elles partagent l'adresse de l'utilisateur. timer variable.

Avec cette modification, vous fournissez un identifiant unique pour chaque rappel, et ces identifiants uniques sont utilisés pour séparer tous les événements de délai d'attente.

2 votes

J'ai combiné cela en redimensionnant des graphiques Highcharts en plein écran (non html5) et cela fonctionne très bien.

0 votes

Absolument incroyable !

2 votes

Comme j'ai beaucoup profité de votre réponse, j'ai pensé partager un prototype fonctionnel du code que vous avez fourni pour le reste de la communauté : jsfiddle.net/h6h2pzpu/3 . Profitez-en tous !

141voto

Carlos Martinez Points 3151

Je préfère créer un événement :

$(window).bind('resizeEnd', function() {
    //do something, window hasn't changed size in 500ms
});

Voici comment le créer :

 $(window).resize(function() {
        if(this.resizeTO) clearTimeout(this.resizeTO);
        this.resizeTO = setTimeout(function() {
            $(this).trigger('resizeEnd');
        }, 500);
    });

Vous pourriez l'avoir dans un fichier javascript global quelque part.

0 votes

J'ai utilisé cette solution. Mais à long terme, je voudrais mettre en œuvre la même solution que celle de Brahn.

0 votes

Cela vous permet de vous lier à cet événement partout, et pas seulement dans une fonction, en supposant que vous avez plusieurs pages / fichiers .js nécessitant des réactions distinctes, bien sûr.

0 votes

Cela n'a pas fonctionné pour moi, mais la réponse de DusanV a fait l'affaire.

122voto

CMS Points 315406

J'utilise la fonction suivante pour retarder des actions répétées, elle fonctionnera pour votre cas :

var delay = (function(){
  var timer = 0;
  return function(callback, ms){
    clearTimeout (timer);
    timer = setTimeout(callback, ms);
  };
})();

Utilisation :

$(window).resize(function() {
    delay(function(){
      alert('Resize...');
      //...
    }, 500);
});

La fonction de rappel qui lui est passée, ne s'exécutera que lorsque le dernier appel à delay aura été fait après le temps spécifié, sinon un timer sera remis à zéro, je trouve cela utile pour d'autres buts comme détecter quand l'utilisateur a arrêté de taper, etc...

6 votes

Je pense que cette approche peut échouer si elle est utilisée plusieurs fois (par exemple si différentes parties du code configurent des rappels à $(window).resize ) car ils partageront tous le timer variable. Voir ma réponse ci-dessous pour la solution proposée.

0 votes

Très bien ! Fonctionne comme un charme ! J'aime vos réponses... simples et élégantes !

74voto

JT. Points 442

Si vous avez installé Underscore.js, vous pourriez :

$(window).resize(_.debounce(function(){
    alert("Resized");
},500));

1 votes

Même si tu ne veux pas inclure Underscore, récupère au moins la source pour ça : underscorejs.org/docs/underscore.html#section-67

0 votes

Debounce est la bonne technique ici, c'est juste une question de mise en œuvre. Et c'est l'implémentation supérieure si Underscore/Lodash est déjà une dépendance du projet.

0 votes

C'est maintenant ce que j'utilise,

23voto

DusanV Points 39

Certaines des solutions mentionnées précédemment n'ont pas fonctionné pour moi, même si elles sont d'usage plus général. Alternativement, j'ai J'ai trouvé celui-ci qui a fait le travail sur le redimensionnement de la fenêtre :

$(window).bind('resize', function(e){
    window.resizeEvt;
    $(window).resize(function(){
        clearTimeout(window.resizeEvt);
        window.resizeEvt = setTimeout(function(){
        //code to do after window is resized
        }, 250);
    });
});

1 votes

Seul votre exemple a fonctionné pour moi... les autres ci-dessus n'ont pas fonctionné ! Je ne sais pas pourquoi votre réponse n'a pas été sélectionnée.

0 votes

Je ne comprends pas pourquoi il faut attraper l'événement resize à l'intérieur de l'événement resize, mais ça marche pour moi aussi...

0 votes

Mumbo Jumbo, je pense que c'est parce que les autres se concentrent sur la généralisation, en cherchant une solution à tout problème de ce type (appels multiples d'une fonction).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X