JavaScript window resize event

2018-12-31 04:09发布

How can I hook into a browser window resize event?

There's a jQuery way of listening for resize events but I would prefer not to bring it into my project for just this one requirement.

12条回答
人气声优
2楼-- · 2018-12-31 04:44

The resize event should never be used directly as it is fired continuously as we resize.

Use a debounce function to mitigate the excess calls.

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

Here's a common debounce floating around the net, though do look for more advanced ones as featuerd in 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);
    };
};

This can be used like so...

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

It will never fire more than once every 200ms.

For mobile orientation changes use:

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

Here's a small library I put together to take care of this neatly.

查看更多
浪荡孟婆
3楼-- · 2018-12-31 04:51

Thanks for referencing my blog post at http://mbccs.blogspot.com/2007/11/fixing-window-resize-event-in-ie.html.

While you can just hook up to the standard window resize event, you'll find that in IE, the event is fired once for every X and once for every Y axis movement, resulting in a ton of events being fired which might have a performance impact on your site if rendering is an intensive task.

My method involves a short timeout that gets cancelled on subsequent events so that the event doesn't get bubbled up to your code until the user has finished resizing the window.

查看更多
长期被迫恋爱
4楼-- · 2018-12-31 04:52

Solution for 2018+:

You should use ResizeObserver. It will be a browser-native solution that has a much better performance than to use the resize event. In addition, it not only supports the event on the document but also on arbitrary 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);

Currently, only Chrome supports it but other browsers will likely follow (soon). For now you have to use a polyfill.

查看更多
听够珍惜
5楼-- · 2018-12-31 04:53

First off, I know the addEventListener method has been mentioned in the comments above, but I didn't see any code. Since it's the preferred approach, here it is:

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

Here's a working sample.

查看更多
时光乱了年华
6楼-- · 2018-12-31 04:53
window.onresize = function() {
    // your code
};
查看更多
呛了眼睛熬了心
7楼-- · 2018-12-31 04:53
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_];
        }
    }
}
查看更多
登录 后发表回答