【问题标题】:DOM onresize eventDOM onresize 事件
【发布时间】:2025-12-04 10:20:06
【问题描述】:

如果我有这个

window.onresize = function() {
  alert('resized!!');
};

我的函数在调整大小的整个过程中被触发了多次,但我想捕获调整大小的完成。这是在 IE 中。

有什么想法吗?那里有各种各样的想法,但到目前为止对我没有用(例如 IE 的假定 window.onresizeend 事件。)

【问题讨论】:

  • 您的 windows 版本配置为在 调整窗口大小时重新绘制屏幕。所以事件正在正确触发。您可以在系统属性的高级性能设置中进行调整。

标签: javascript dom onresize


【解决方案1】:

在这种情况下,我会强烈建议去抖动。我发现在 JavaScript 中执行此操作的最简单、有效和可靠的方法是 Ben Alman's jQuery plugin, Throttle/Debounce(可以使用或不使用 jQuery - 我知道......听起来很奇怪)。

使用去抖动,执行此操作的代码将非常简单:

$(window).resize($.debounce(1000, function() {
   // Handle your resize only once total, after a one second calm.
   ...
}));

希望这可以帮助某人。 ;)

【讨论】:

  • 第一行更像 $(window).resize($.debounce(1000, true, function(e) {
  • @Philppe:这很有趣,因为 Ben 的示例不是这样说的,我的工作代码中也不是这样。
  • @Lance May :这很奇怪,因为如果您查看他的示例页面 jsfiddle.net/cowboy/cTZJU/show 的来源,它与我写的完全一样。也许他更新了他的剧本?编辑你的答案,我会投票。
  • @Philippe:我在帖子中提供的链接是我从他那里看到的关于此事的唯一一页(因为那里肯定很清楚)。该页面上直接显示的 debounce 示例正好显示 $('input:text').keyup( $.debounce( 250, ajax_lookup ) );,这也是我在自己的代码中使用的内容。您降低我排名的... true, ... 选项明确说明为可选和默认值:“Debounced with at_begin specified as false or unspecified:”。
  • 我有一个演示,您的线路出错,但我的线路没有。 'new' 关键字使 IE7 成为 javascript 'error on object blabla'。如果您可以编辑您的帖子,我将可以投票。
【解决方案2】:

当我想在调整大小后做某事时,我总是使用它。对setTimeoutclearTimeout 的调用对调整大小的速度没有任何明显影响,因此多次调用它们不是问题。

var timeOut = null;
var func = function() { /* snip, onresize code here */};
window.onresize = function(){
   if(timeOut != null) clearTimeout(timeOut);
   timeOut = setTimeout(func, 100);
}

【讨论】:

    【解决方案3】:

    并不完美,但它应该为您提供所需的开始。

    var initialX = null;
    var initialY = null;
    var lastResize = null;
    var waiting = false;
    var first = true;
    var id = 0;
    
    function updateResizeTime()
    {
        if (initialX === event.clientX && initialY === event.clientY)
        {
            return;
        }
    
        initialX = event.clientX;
        initialY = event.clientY;
    
        if (first)
        {
            first = false;
            return;
        }
    
        lastResize = new Date();            
        if (!waiting && id == 0)
        {
            waiting = true;
            id = setInterval(checkForResizeEnd, 1000);
        }
    }
    
    function checkForResizeEnd()
    {
        if ((new Date()).getTime() - lastResize.getTime() >= 1000)
        {
            waiting = false;
            clearInterval(id);
            id = 0;
            alert('hey!');
        }
    }
    
    window.onresize = function()
    {
        updateResizeTime();
    }
    

    【讨论】:

      【解决方案4】:

      您会收到多个事件,因为确实有多个事件。 Windows 会在您拖动窗口时多次执行调整大小的动画(默认情况下,我认为您可以在注册表中更改它)。

      您可以做的是添加延迟。每次 IE 事件触发时执行 clearTimeout, setTimout(myResize,1000)。然后,只有最后一个会进行实际的调整大小。

      【讨论】:

      • 我认为您不必担心注册表。我认为它在 Windows 的性能设置面板中。具有不同选项的选项,如菜单动画、阴影等。
      【解决方案5】:

      简单的纯 javascript 解决方案,只需将 1000 int 值更改为更低以获得更高的响应速度

              var resizing = false;
              window.onresize = function() {
                  if(resizing) return;
                  console.log("resize");
                  resizing = true;
                  setTimeout(function() {resizing = false;}, 1000);
              };
      

      【讨论】:

        【解决方案6】:

        不确定这是否有帮助,但由于它似乎工作得很好,就在这里。 我从上一篇文章中提取了 sn-p 并稍作修改。函数 doCenter() 首先将 px 转换为 em,然后减去对象的宽度并将余数除以 2。结果分配为左边距。执行 doCenter() 以使对象居中。再次执行 doCenter() 调整窗口大小时会触发超时。

        function doCenter() {
        document.getElementById("menuWrapper").style.position = "fixed";
        var getEM = (window.innerWidth * 0.063);
        document.getElementById("menuWrapper").style.left = (getEM - 40) / 2 + "em";
        }
        
        doCenter();
        
        var timeOut = null;
        var func = function() {doCenter()};
        window.onresize = function(){
            if (timeOut != null) clearTimeout(timeOut);
            timeOut = setTimeout(func, 100);
        };
        

        【讨论】:

          【解决方案7】:

          我喜欢 Pim Jager 的优雅解决方案,但我认为最后有一个额外的括号,我认为 setTimeout 应该是“timeOut = setTimeout(func,100);”

          这是我使用 Dojo 的版本(假设定义了一个名为 demo_resize() 的函数)...

          var _semaphorRS = null; dojo.connect(window,"resize",function(){ if (_semaphorRS != null) clearTimeout(_semaphorRS); _semaphorRS = setTimeout(demo_resize, 500); });

          注意:在我的版本中,尾随括号是必需的。

          【讨论】: