Question Événement de redimensionnement de la fenêtre JavaScript


Comment puis-je me connecter à un événement de redimensionnement de la fenêtre du navigateur?

Il y a une façon d'écouter jQuery pour les événements de redimensionnement mais je préférerais ne pas l'inclure dans mon projet pour cette seule exigence.


494
2018-03-13 08:50


origine


Réponses:


jQuery ne fait qu'emballer la norme resize Événement DOM, par exemple.

window.onresize = function(event) {
    ...
};

jQuery mai faites un peu de travail pour vous assurer que l'événement de redimensionnement est systématiquement lancé dans tous les navigateurs, mais je ne suis pas sûr que les navigateurs diffèrent, mais je vous encourage à tester Firefox, Safari et IE.


537
2018-03-13 08:58



Ne remplacez jamais la fonction window.onresize.

Au lieu de cela, créez une fonction pour ajouter un écouteur d'événement à l'objet ou à l'élément. Cela vérifie et incase les auditeurs ne fonctionnent pas, alors il remplace la fonction de l'objet en dernier recours. C'est la méthode préférée utilisée dans les bibliothèques telles que jQuery.

object: l'élément ou l'objet fenêtre
type: redimensionner, faire défiler (type d'événement)
callback: la référence de la fonction

var addEvent = function(object, type, callback) {
    if (object == null || typeof(object) == 'undefined') return;
    if (object.addEventListener) {
        object.addEventListener(type, callback, false);
    } else if (object.attachEvent) {
        object.attachEvent("on" + type, callback);
    } else {
        object["on"+type] = callback;
    }
};

Alors l'utilisation est comme ceci:

addEvent(window, "resize", function_reference);

ou avec une fonction anonyme:

addEvent(window, "resize", function(event) {
  console.log('resized');
});

471
2018-06-30 14:19



Tout d'abord, je connais le addEventListener méthode a été mentionnée dans les commentaires ci-dessus, mais je n'ai vu aucun code. Puisque c'est l'approche préférée, la voici:

window.addEventListener('resize', function(event){
  // do stuff here
});

Voici un exemple de travail.


409
2017-08-29 20:32



Je pense que la réponse correcte a déjà été fournie par @Alex V, mais la réponse nécessite une certaine modernisation car elle a plus de cinq ans.

Il y a deux problèmes principaux:

  1. Ne jamais utiliser object en tant que nom de paramètre. C'est un mot réservé. Cela étant dit, la fonction fournie par @Alex V ne fonctionnera pas dans strict mode.

  2. le addEvent fonction fournie par @Alex V ne retourne pas la event object si la addEventListener méthode est utilisée. Un autre paramètre devrait être ajouté à la addEvent fonction pour permettre cela.

NOTE: Le nouveau paramètre à addEvent a été rendu facultatif pour que la migration vers cette nouvelle version de fonction ne brise aucun appel précédent à cette fonction. Toutes les utilisations héritées seront prises en charge.

Voici la mise à jour addEvent fonction avec ces changements:

/*
    function: addEvent

    @param: obj         (Object)(Required)

        -   The object which you wish
            to attach your event to.

    @param: type        (String)(Required)

        -   The type of event you
            wish to establish.

    @param: callback    (Function)(Required)

        -   The method you wish
            to be called by your
            event listener.

    @param: eventReturn (Boolean)(Optional)

        -   Whether you want the
            event object returned
            to your callback method.
*/
var addEvent = function(obj, type, callback, eventReturn)
{
    if(obj == null || typeof obj === 'undefined')
        return;

    if(obj.addEventListener)
        obj.addEventListener(type, callback, eventReturn ? true : false);
    else if(obj.attachEvent)
        obj.attachEvent("on" + type, callback);
    else
        obj["on" + type] = callback;
};

Un exemple d'appel au nouveau addEvent fonction:

var watch = function(evt)
{
    /*
        Older browser versions may return evt.srcElement
        Newer browser versions should return evt.currentTarget
    */
    var dimensions = {
        height: (evt.srcElement || evt.currentTarget).innerHeight,
        width: (evt.srcElement || evt.currentTarget).innerWidth
    };
};

addEvent(window, 'resize', watch, true);

15
2017-10-05 18:38



L'événement de redimensionnement ne doit jamais être utilisé directement car il est déclenché en continu lorsque nous redimensionnons.

Utilisez une fonction anti-rebond pour limiter les appels excédentaires.

window.addEventListener('resize',debounce(handler, delay, immediate),false);

Voici un debounce commun flottant autour du filet, bien que recherchent des plus avancés comme featuerd dans lodash.

const debounce = (func, wait, immediate) => {
    var timeout;
    return () => {
        const context = this, args = arguments;
        const later = function() {
            timeout = null;
            if (!immediate) func.apply(context, args);
        };
        const callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
    };
};

Cela peut être utilisé comme ça ...

window.addEventListener('resize', debounce(() => console.log('hello'),
200, false), false);

Il ne tirera jamais plus d'une fois toutes les 200ms.

Pour les changements d'orientation mobiles, utilisez:

window.addEventListener('orientationchange', () => console.log('hello'), false);

Voici un petite bibliothèque J'ai mis ensemble pour prendre soin de cela soigneusement.


14
2018-04-06 03:12



Merci d'avoir référencé mon article de blog à http://mbccs.blogspot.com/2007/11/fixing-window-resize-event-in-ie.html.

Alors que vous pouvez simplement vous connecter à l'événement standard de redimensionnement de la fenêtre, vous constaterez que dans IE, l'événement est déclenché une fois pour chaque X et une fois pour chaque mouvement de l'axe Y, ce qui génère une tonne d'événements impact sur votre site si le rendu est une tâche intensive.

Ma méthode implique un court délai d'attente qui est annulé sur les événements ultérieurs afin que l'événement ne soit pas barboter à votre code jusqu'à ce que l'utilisateur a terminé le redimensionnement de la fenêtre.


13
2017-12-05 18:50



window.onresize = function() {
    // your code
};

10
2017-11-16 05:27



Le post de blog suivant peut vous être utile: Correction de l'événement de redimensionnement de la fenêtre dans IE

Il fournit ce code:

Sys.Application.add_load(function(sender, args) {
    $addHandler(window, 'resize', window_resize);
});

var resizeTimeoutId;

function window_resize(e) {
     window.clearTimeout(resizeTimeoutId);
     resizeTimeoutId = window.setTimeout('doResizeCode();', 10);
}

6
2018-03-13 09:00



Solution pour 2018+:

Tu devrais utiliser ResizeObserver. Ce sera une solution native du navigateur qui a une bien meilleure performance que d'utiliser le resize un événement. En outre, il ne prend pas seulement en charge l'événement sur le document mais aussi arbitraire elements.

var ro = new ResizeObserver( entries => {
  for (let entry of entries) {
    const cr = entry.contentRect;
    console.log('Element:', entry.target);
    console.log(`Element size: ${cr.width}px x ${cr.height}px`);
    console.log(`Element padding: ${cr.top}px ; ${cr.left}px`);
  }
});

// Observe one or multiple elements
ro.observe(someElement);

Actuellement, seulement Chrome le supporte mais d'autres navigateurs suivront probablement (bientôt). Pour l'instant, vous devez utiliser un polyfill.


3
2018-03-20 10:00



Les solutions mentionnées ci-dessus fonctionneront si tout ce que vous voulez faire est de redimensionner la fenêtre et la fenêtre uniquement. Toutefois, si vous souhaitez que la redimensionnement soit propagé aux éléments enfants, vous devrez propager l'événement vous-même. Voici un exemple de code pour le faire:

window.addEventListener("resize", function () {
  var recResizeElement = function (root) {
    Array.prototype.forEach.call(root.childNodes, function (el) {

      var resizeEvent = document.createEvent("HTMLEvents");
      resizeEvent.initEvent("resize", false, true);
      var propagate = el.dispatchEvent(resizeEvent);

      if (propagate)
        recResizeElement(el);
    });
  };
  recResizeElement(document.body);
});

Notez qu'un élément enfant peut appeler

 event.preventDefault();

sur l'objet d'événement transmis en tant que premier Arg de l'événement de redimensionnement. Par exemple:

var child1 = document.getElementById("child1");
child1.addEventListener("resize", function (event) {
  ...
  event.preventDefault();
});

2
2018-04-20 03:55