JavaScript窗口调整大小事件

时间:2009-03-13 08:50:23

标签: javascript javascript-events window-resize

如何挂钩浏览器窗口调整大小事件?

a jQuery way of listening for resize events但我不想仅仅针对这一要求将其纳入我的项目中。

13 个答案:

答案 0 :(得分:596)

jQuery只是包装标准的resize DOM事件,例如

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

jQuery 可以做一些工作以确保在所有浏览器中一致地触发resize事件,但我不确定是否有任何浏览器不同,但我鼓励你测试Firefox,Safari和IE。

答案 1 :(得分:503)

永远不要覆盖window.onresize函数。

相反,创建一个函数以将Event Listener添加到对象或元素。 这会检查并使侦听器不起作用,然后它会覆盖对象的函数作为最后的手段。这是jQuery等库中使用的首选方法。

object:元素或窗口对象
type:调整大小,滚动(事件类型)
callback:函数参考

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;
    }
};

然后使用是这样的:

addEvent(window, "resize", function_reference);

或使用匿名函数:

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

答案 2 :(得分:484)

首先,我知道上面的评论中提到了addEventListener方法,但我没有看到任何代码。由于它是首选方法,因此它是:

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

Here's a working sample

答案 3 :(得分:25)

不应该直接使用resize事件,因为在我们调整大小时会连续触发它。

使用去抖功能来缓解多余的电话。

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

这是一个常见的辩论,在网络上漂浮,但在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);
    };
};

这可以像这样使用......

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

它不会每200毫秒发射一次以上。

对于移动方向更改,请使用:

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

这是一个small library我整理好整齐照顾这个。

答案 4 :(得分:15)

我相信@Alex V已经提供了正确的答案,但答案确实需要一些现代化,因为现在它已经超过五年了。

有两个主要问题:

  1. 切勿使用object作为参数名称。这是一个保留的词。话虽如此,@ Alex V提供的功能在strict mode中不起作用。

  2. 如果使用addEvent方法,则@Alex V提供的event object函数不会返回addEventListener。应该在addEvent函数中添加另一个参数以允许此操作。

  3. 注意:addEvent的新参数已设为可选,因此迁移到此新功能版本不会破坏之前对此功能的任何调用。将支持所有旧版用途。

    以下是更新后的addEvent功能,其中包含以下更改:

    /*
        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;
    };
    

    调用新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);
    

答案 5 :(得分:12)

感谢您在http://mbccs.blogspot.com/2007/11/fixing-window-resize-event-in-ie.html引用我的博文。

虽然您可以直接连接到标准窗口调整大小事件,但您会发现在IE中,每个X触发一次事件,每个Y轴移动触发一次事件,导致大量事件被触发如果渲染是一项密集型任务,则会对您的网站产生性能影响。

我的方法涉及在后续事件中取消的短暂超时,以便在用户完成窗口大小调整之前,事件不会冒泡到您的代码。

答案 6 :(得分:11)

2018 +的解决方案:

您应该使用ResizeObserver。它将是一个浏览器本机解决方案,其性能远远优于使用resize事件。此外,它不仅支持document上的活动,还支持任意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);

目前,只有Chrome supports it but other browsers will likely follow(很快)。现在你必须使用polyfill

答案 7 :(得分:9)

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

答案 8 :(得分:6)

以下博文可能对您有用:Fixing the window resize event in IE

它提供了以下代码:

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);
}

答案 9 :(得分:2)

如果你想要做的只是调整窗口和窗口的大小,上面提到的解决方案将会起作用。但是,如果要将调整大小传播到子元素,则需要自己传播事件。以下是一些示例代码:

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);
});

请注意,子元素可以调用

 event.preventDefault();

作为resize事件的第一个Arg传入的事件对象。例如:

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

答案 10 :(得分:1)

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_];
        }
    }
}

答案 11 :(得分:0)

<script language="javascript">
    window.onresize = function() {
    document.getElementById('ctl00_ContentPlaceHolder1_Accordion1').style.height = '100%';
} 

</script>

答案 12 :(得分:0)

您可以使用ok for small projects

以下方法
curl -k ::::::::::::::
curl -k /local/scripts/shell/checker/temp/allCurls.txt
curl -k ::::::::::::::

<body onresize="yourHandler(event)">
function yourHandler(e) {
  console.log('Resized:', e.target.innerWidth)
}