跨浏览器窗口调整大小事件 - JavaScript / jQuery

242

如何正确(现代)地监控窗口调整大小事件,使其在Firefox,WebKit和Internet Explorer中均可正常工作?

你能同时开启/关闭两个滚动条吗?


我也在研究这个问题。我想尝试应用这里提供的解决方案,但是我担心我不理解语法:$(window)。那是jQuery特定的东西吗? - Byff
1
Byff,是的,$(window) 是 jQuery 的结构。window.onresize 是原始 JavaScript 中的等效代码。 - Andrew Hedges
这个演示可以帮助任何人在所有浏览器上进行测试 http://jsfiddle.net/subodhghulaxe/bHQV5/2/ - Subodh Ghulaxe
window.dispatchEvent(new Event('resize')); 可以触发 JavaScript 中的窗口调整大小事件。详情请参考 https://dev59.com/i3I-5IYBdhLWcg3whImk - Dylan Valade
在移动设备上的 Opera 浏览器中,每次顶部工具栏(浏览器 UI)出现或隐藏时都会触发它。 - psur
11个回答

370

对于此事,jQuery 已经有了一个内置方法

$(window).resize(function () { /* do something */ });

为了提高用户界面的响应性,你可以考虑使用setTimeout在一定的毫秒数后调用你的代码,以下示例启发自这里

function doSomething() {
    alert("I'm done resizing for the moment");
};

var resizeTimer;
$(window).resize(function() {
    clearTimeout(resizeTimer);
    resizeTimer = setTimeout(doSomething, 100);
});

34
当通过按钮将窗口扩展到全屏时,为什么此事件没有被触发? - Sly
2
@Sly: $('.button').on({ click: function(){ /* 你的代码 */ $(window).trigger('resize') }) - Zack Zatkin-Gold
6
以JavaScript为例,Elijah,你所写的并不正确(除非你是在使用new进行构造)。 - Yoh Suzuki
2
如果您不想使用jQuery,请参见下面我的答案 - Jondlm
3
值得一提的是,这个 jQuery 函数会在当前应该在窗口大小改变时调用的函数列表中“添加”一个函数调用。它不会覆盖当前已计划在窗口大小改变时执行的现有事件。 - RTF
显示剩余4条评论

49
$(window).bind('resize', function () { 

    alert('resize');

});

4
我更喜欢采用绑定方法,因为resize()方法实际上是完整绑定方法的快捷方式。而且我通常发现一个元素需要应用不止一个事件处理程序。 - Mike Kormendy
@Mike - 不仅如此,我猜测resize方法没有“unbind”方法,以便您想要删除监听器。 "bind"绝对是正确的选择! - Shane

44

这是一种非使用jQuery的方式来监听resize事件:

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

它适用于所有现代浏览器。它不会为你限制任何内容。 这里有一个示例,展示了它的效果。


这个解决方案在IE中不起作用。修复版本支持IE DOM:https://dev59.com/questions/82w05IYBdhLWcg3w72XN - Sergey
1
它不会为您限制任何内容。您能否详细说明一下?它应该/会限制什么?这是否与事件连续多次触发有关? - josinalvo
@josinalvo 通常当你监听一个频繁触发的事件时,你会想要防抖 (例如 lodash)它,这样你就不会在程序中造成瓶颈。 - Jondlm

17

很抱歉又翻出了一个旧的帖子,但如果有人不想使用jQuery,可以使用以下代码:

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

8
请注意,这将覆盖可能绑定到window.onresize的任何现有处理程序。 如果您的脚本必须在其他脚本的生态系统中运行,您不应该假设您的脚本是唯一想要在窗口大小调整时执行某些操作的脚本。 如果您无法使用诸如jQuery之类的框架,则至少应考虑获取现有的window.onresize,并将处理程序添加到其末尾,而不是完全覆盖它。 - Tom Auger
2
@TomAuger 你至少应该考虑获取现有的window.onresize,并将处理程序添加到它的末尾。也许你是想要相反的,即“在你的处理程序结束时调用现有的处理程序”?我真的很想看到一个JavaScript代码,可以将一些内容添加到已经存在的函数的末尾 :-) - Tomas
我在某种程度上理解你的观点 - 你的新onResize处理程序需要包装现有的onResize。然而,在调用原始的onResize处理程序之后,它不必立即调用你想要添加到onResize中的函数。因此,你仍然可以确保你的新onResize函数在原始onResize函数之后执行,这可能比反过来更好。 - Tom Auger

8

既然您使用jQuery,这个插件似乎可以解决问题。


5

使用 jQuery 1.9.1,我刚刚发现尽管在技术上相同,但这在 IE10 中不能正常工作(但在 Firefox 中可以):

// did not work in IE10
$(function() {
    $(window).resize(CmsContent.adjustSize);
});

虽然这在两个浏览器中都有效:

// did work in IE10
$(function() {
    $(window).bind('resize', function() {
        CmsContent.adjustSize();
    };
});
编辑:
)* 实际上并不是技术上完全相同,正如WraithKennyHenry Blyth在评论中所指出和解释的那样。

1
有两个更改,哪一个起了作用?(是将.resize()更改为.bind('resize')还是添加匿名函数?我认为是第二个。) - WraithKenny
@WraithKenny 说得好。很可能是添加匿名函数使其工作。我不记得我是否尝试过。 - bassim
1
在第一种情况下,adjustSize方法失去了它的上下文this,而第二个调用CmsContent.adjustSize()保留了this,即this === CmsContent。如果在adjustSize方法中需要CmsContent实例,则第一种情况将失败。第二种情况适用于每种函数调用,因此建议始终传递匿名函数。 - Henry Blyth
1
@HenryBlyth 谢谢!+1 - bassim

4

jQuery默认提供$(window).resize()函数:

<script type="text/javascript">
// function for resize of div/span elements
var $window = $( window ),
    $rightPanelData = $( '.rightPanelData' )
    $leftPanelData = $( '.leftPanelData' );

//jQuery window resize call/event
$window.resize(function resizeScreen() {
    // console.log('window is resizing');

    // here I am resizing my div class height
    $rightPanelData.css( 'height', $window.height() - 166 );
    $leftPanelData.css ( 'height', $window.height() - 236 );
});
</script> 

3
我认为jQuery插件"jQuery resize event"是最好的解决方案,因为它会处理节流事件,使其在所有浏览器中都能正常工作。它类似于Andrew的回答,但更好,因为您可以将调整大小事件挂钩到特定元素/选择器以及整个窗口。这为编写清晰的代码打开了新的可能性。
该插件可在此处获取。
如果添加了大量侦听器,则存在性能问题,但对于大多数使用情况而言,它非常完美。

0
除了提到的窗口调整函数之外,重要的是要理解如果不对事件进行防抖处理,调整大小事件会频繁触发。
Paul Irish有一个非常出色的函数,可以大大减少调整大小的调用次数。强烈推荐使用。可跨浏览器使用。前几天在IE8中测试过,一切正常。

http://www.paulirish.com/2009/throttled-smartresize-jquery-event-handler/

请务必查看演示以查看差异。

以下是完整的函数。

(function($,sr){

  // debouncing function from John Hann
  // http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/
  var debounce = function (func, threshold, execAsap) {
      var timeout;

      return function debounced () {
          var obj = this, args = arguments;
          function delayed () {
              if (!execAsap)
                  func.apply(obj, args);
              timeout = null;
          };

          if (timeout)
              clearTimeout(timeout);
          else if (execAsap)
              func.apply(obj, args);

          timeout = setTimeout(delayed, threshold || 100);
      };
  }
  // smartresize 
  jQuery.fn[sr] = function(fn){  return fn ? this.bind('resize', debounce(fn)) : this.trigger(sr); };

})(jQuery,'smartresize');


// usage:
$(window).smartresize(function(){
  // code that takes it easy...
});

0

希望这对jQuery有所帮助

首先定义一个函数,如果已经存在函数则跳过下一步。

 function someFun() {
 //use your code
 }

浏览器调整大小使用如下。

 $(window).on('resize', function () {
    someFun();  //call your function.
 });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接