JQuery:如何仅在完成调整大小后才调用 RESIZE 事件?

IT技术 javascript jquery html
2021-01-11 02:36:35

浏览器窗口完成调整大小后如何调用函数?

我正在尝试这样做,但遇到了问题。我正在使用 JQuery Resize 事件函数:

$(window).resize(function() {
  ... // how to call only once the browser has FINISHED resizing?
});

但是,如果用户手动调整浏览器窗口的大小,则会连续调用此函数这意味着,它可能会在短时间内调用此函数数十次。

我如何可以调用调整大小功能只是一个时间(一旦浏览器窗口已完成调整大小)?

更新

也不必使用全局变量。

6个回答

这是一个使用 thejh 指令的示例

您可以将引用 ID 存储到任何 setInterval 或 setTimeout。像这样:

var loop = setInterval(func, 30);

// some time later clear the interval
clearInterval(loop);
感谢更新,但它似乎仍然使用全局变量。您能否将其更新为不需要全局变量(var id)。谢谢
2021-03-12 02:36:35
我想你错过了帖子末尾的链接......检查一下:jsfiddle.net/Zevan/c9UE5/5
2021-03-22 02:36:35
我喜欢这段代码如此简单。有什么方法可以使这项工作无需使用全局变量?
2021-03-27 02:36:35
如果我看到如何在没有全局变量的情况下执行此操作,我会将其设为“已接受的答案”
2021-03-29 02:36:35
没问题。有几种方法。我已经编辑了答案以反映我能想到的最简单的答案。
2021-03-31 02:36:35

去抖

function debouncer( func , timeout ) {
   var timeoutID , timeout = timeout || 200;
   return function () {
      var scope = this , args = arguments;
      clearTimeout( timeoutID );
      timeoutID = setTimeout( function () {
          func.apply( scope , Array.prototype.slice.call( args ) );
      } , timeout );
   }
}


$( window ).resize( debouncer( function ( e ) {
    // do stuff 
} ) );

请注意,您可以将此方法用于您想要去抖动的任何内容(关键事件等)。

调整超时参数以获得最佳预期效果。

如果您已经在使用该库,Underscore.js 有一个很好的实现。underscorejs.org/#debounce
2021-03-13 02:36:35
@user43493:它调用 cuntion func,内部this指针指向scope,并使用Array.prototype.slice.call(args)(从 中生成标准数组args)作为参数
2021-03-18 02:36:35
这是一个可重用的抽象,因此您不必手动编码超时或自己跟踪全局 timeoutID。您可以将它用于更多的方式,而不仅仅是调整窗口大小;) 例如通过传递更高的超时参数来消除提交按钮的抖动。您可以选择代码较少的解决方案,但我建议您将此代码段保留在您的工具包中,您以后会很感激的 ;)
2021-03-19 02:36:35
我只是尝试运行它,它似乎运行了TWICE"$("body").append("<br/>DONE!");"替换了"// do stuff " 它在浏览器调整大小时调用它两次
2021-03-28 02:36:35
oop...我忘记了一个相当重要的部分(实际上是设置 timeoutID)...现在已修复,请再试一次;)
2021-03-30 02:36:35

您可以使用setTimeout()clearTimeout()结合使用jQuery.data

$(window).resize(function() {
    clearTimeout($.data(this, 'resizeTimer'));
    $.data(this, 'resizeTimer', setTimeout(function() {
        //do something
        alert("Haven't resized in 200ms!");
    }, 200));
});

更新

我编写了一个扩展来增强 jQuery 的默认on(& bind)-事件处理程序。如果在给定的时间间隔内未触发事件,它将一个或多个事件的事件处理函数附加到所选元素。如果您只想在延迟后触发回调,例如调整大小事件,或者其他情况,这将非常有用。 https://github.com/yckart/jquery.unevent.js

;(function ($) {
    var methods = { on: $.fn.on, bind: $.fn.bind };
    $.each(methods, function(k){
        $.fn[k] = function () {
            var args = [].slice.call(arguments),
                delay = args.pop(),
                fn = args.pop(),
                timer;

            args.push(function () {
                var self = this,
                    arg = arguments;
                clearTimeout(timer);
                timer = setTimeout(function(){
                    fn.apply(self, [].slice.call(arg));
                }, delay);
            });

            return methods[k].apply(this, isNaN(delay) ? arguments : args);
        };
    });
}(jQuery));

像任何其他onbind-event 处理程序一样使用它,除了您可以将额外的参数作为最后一个传递:

$(window).on('resize', function(e) {
    console.log(e.type + '-event was 200ms not triggered');
}, 200);

http://jsfiddle.net/ARTsinn/EqqHx/

每天做同样的谷歌搜索。并来到这段代码的同一页面。希望我能记住它哈哈。
2021-03-22 02:36:35
var lightbox_resize = false;
$(window).resize(function() {
    console.log(true);
    if (lightbox_resize)
        clearTimeout(lightbox_resize);
    lightbox_resize = setTimeout(function() {
        console.log('resize');
    }, 500);
});
我最喜欢这个,但为什么不在你的条件语句中使用大括号呢?我知道它可以在没有它们的情况下工作,但其他开发人员很难看到;)
2021-03-14 02:36:35

只是为了补充上述内容,由于滚动条弹出和弹出而导致不需要的调整大小事件是很常见的,这里有一些代码可以避免这种情况:

function registerResize(f) {
    $(window).resize(function() {
        clearTimeout(this.resizeTimeout);
        this.resizeTimeout = setTimeout(function() {
            var oldOverflow = document.body.style.overflow;
            document.body.style.overflow = "hidden";
            var currHeight = $(window).height(),
                currWidth = $(window).width();
            document.body.style.overflow = oldOverflow;

            var prevUndefined = (typeof this.prevHeight === 'undefined' || typeof this.prevWidth === 'undefined');
            if (prevUndefined || this.prevHeight !== currHeight || this.prevWidth !== currWidth) {
                //console.log('Window size ' + (prevUndefined ? '' : this.prevHeight + "," + this.prevWidth) + " -> " + currHeight + "," + currWidth);
                this.prevHeight = currHeight;
                this.prevWidth = currWidth;

                f(currHeight, currWidth);
            }
        }, 200);
    });
    $(window).resize(); // initialize
}

registerResize(function(height, width) {
    // this will be called only once per resize regardless of scrollbars changes
});

jsfiddle