我怎么能挂钩到浏览器窗口调整大小事件?

jQuery有一种监听调整大小事件的方法,但我不希望仅仅为了这一需求而将其引入我的项目中。


当前回答

2018年解决方案+:

您应该使用ResizeObserver。这是一种浏览器原生解决方案,比使用resize事件具有更好的性能。此外,它不仅支持文档上的事件,还支持任意元素上的事件。

var ro = new ResizeObserver(entries => { For (let entry of entries) { const cr = entry.contentRect; console.log(元素:,entry.target); console.log('元素大小:${cr. log。宽度}px x ${cr.height}px '); console.log('元素填充:${cr. log。顶级}px;$ {cr.left} px”); } }); //观察一个或多个元素 ro.observe (someElement);

目前Firefox、Chrome、Safari和Edge支持。对于其他(和旧的)浏览器,您必须使用polyfill。

其他回答

调整大小事件永远不应该直接使用,因为它在我们调整大小时不断被触发。

使用debounce函数来减少多余的调用。

窗口。addEventListener(“resizz”,debounce(handler, delay,即时性),假的);

这是一个常见的反弹漂浮在网上,尽管要寻找更先进的功能在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);

这是一个小的图书馆,我把它整理在一起。

2018年解决方案+:

您应该使用ResizeObserver。这是一种浏览器原生解决方案,比使用resize事件具有更好的性能。此外,它不仅支持文档上的事件,还支持任意元素上的事件。

var ro = new ResizeObserver(entries => { For (let entry of entries) { const cr = entry.contentRect; console.log(元素:,entry.target); console.log('元素大小:${cr. log。宽度}px x ${cr.height}px '); console.log('元素填充:${cr. log。顶级}px;$ {cr.left} px”); } }); //观察一个或多个元素 ro.observe (someElement);

目前Firefox、Chrome、Safari和Edge支持。对于其他(和旧的)浏览器,您必须使用polyfill。

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

主要有两个问题:

永远不要使用object作为参数名。这是一个保留词。话虽如此,@Alex V提供的函数将不能在严格模式下工作。 如果使用了addEventListener方法,@Alex V提供的addEvent函数不会返回事件对象。为此,应该向addEvent函数添加另一个参数。

注意: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);
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_];
        }
    }
}

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

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事件的第一个参数传入的事件对象。例如:

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