web-dev-qa-db-fra.com

Evénement de redimensionnement de la fenêtre JavaScript

Comment puis-je m'accrocher à un événement de redimensionnement de la fenêtre du navigateur?

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

577
Dead account

jQuery est juste en train d'habiller l'événement _ resize DOM standard, par exemple.

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

jQuery may fait quelques travaux pour s'assurer que l'événement de redimensionnement est déclenché de manière cohérente dans tous les navigateurs, mais je ne suis pas sûr que l'un des navigateurs diffère, mais je vous encourage à tester dans Firefox, Safari et IE.

610
olliej

Ne jamais remplacer 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. Cette vérification et si les écouteurs ne fonctionnent pas, alors elle remplace la fonction de l'objet en dernier recours. C'est la méthode préférée utilisée dans des bibliothèques telles que jQuery.

object: l'objet element ou window
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 utiliser est comme ça:

addEvent(window, "resize", function_reference);

ou avec une fonction anonyme:

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

Tout d'abord, je sais que la méthode addEventListener a été mentionnée dans les commentaires ci-dessus, mais je n'ai vu aucun code. Puisque c'est l'approche privilégiée, la voici:

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

Voici un exemple de travail .

500
Jondlm

L'événement de redimensionnement ne doit jamais être utilisé directement car il est déclenché de manière continue lors du redimensionnement.

Utilisez une fonction anti-rebond pour atténuer les appels en excès.

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

Voici un rebond courant qui flotte sur le net, mais recherchez des options plus avancées 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 si ...

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 mobile, utilisez:

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

Voici un petite bibliothèque Je me suis mis ensemble pour prendre soin de cela proprement.

29
Undefined

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

Il y a deux problèmes principaux:

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

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

REMARQUE: le nouveau paramètre addEvent a été rendu facultatif, de sorte que la migration vers cette nouvelle version de la fonction n'enlèvera aucun appel précédent à cette fonction. Toutes les utilisations héritées seront prises en charge.

Voici la fonction addEvent mise à jour avec ces modifications:

/*
    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 à la nouvelle fonction addEvent:

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
WebWanderer

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

Bien que vous puissiez simplement vous connecter à l'événement de redimensionnement de fenêtre standard, 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 des Y, ce qui entraîne le déclenchement d'une tonne d'événements susceptibles d'avoir une performance. impact sur votre site si le rendu est une tâche intensive.

Ma méthode implique un court délai qui est annulé lors d'événements ultérieurs afin que l'événement ne soit pas diffusé dans votre code jusqu'à ce que l'utilisateur ait fini de redimensionner la fenêtre.

12
Steven

Solution pour 2018 +:

Vous devriez utiliser ResizeObserver . Ce sera une solution native pour le navigateur offrant de bien meilleures performances que d’utiliser l’événement resize. De plus, il ne supporte pas seulement l'événement sur la document, mais également sur la elements arbitraire.

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, seul Chrome le prend en charge, mais d'autres navigateurs suivront probablement (bientôt). Pour l'instant, vous devez utiliser un polyfill .

11
str
window.onresize = function() {
    // your code
};
8
saravanakumar

Le 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
lakshmanaraj

Les solutions déjà mentionnées ci-dessus ne fonctionneront que si vous ne souhaitez que redimensionner la fenêtre et la fenêtre uniquement. Toutefois, si vous souhaitez que le redimensionnement soit propagé aux éléments enfants, vous devez 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 é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
rysama
var EM = new events_managment();

EM.addEvent(window, 'resize', function(win,doc, event_){
    console.log('resized');
    //EM.removeEvent(win,doc, event_);
});

function events_managment(){
    this.events = {};
    this.addEvent = function(node, event_, func){
        if(node.addEventListener){
            if(event_ in this.events){
                node.addEventListener(event_, function(){
                    func(node, event_);
                    this.events[event_](win_doc, event_);
                }, true);
            }else{
                node.addEventListener(event_, function(){
                    func(node, event_);
                }, true);
            }
            this.events[event_] = func;
        }else if(node.attachEvent){

            var ie_event = 'on' + event_;
            if(ie_event in this.events){
                node.attachEvent(ie_event, function(){
                    func(node, ie_event);
                    this.events[ie_event]();
                });
            }else{
                node.attachEvent(ie_event, function(){
                    func(node, ie_event);
                });
            }
            this.events[ie_event] = func;
        }
    }
    this.removeEvent = function(node, event_){
        if(node.removeEventListener){
            node.removeEventListener(event_, this.events[event_], true);
            this.events[event_] = null;
            delete this.events[event_];
        }else if(node.detachEvent){
            node.detachEvent(event_, this.events[event_]);
            this.events[event_] = null;
            delete this.events[event_];
        }
    }
}
1
THE AMAZING
<script language="javascript">
    window.onresize = function() {
    document.getElementById('ctl00_ContentPlaceHolder1_Accordion1').style.height = '100%';
} 

</script>
0
Rob Herring