iphone/ipad 触发意外的调整大小事件

Posted

技术标签:

【中文标题】iphone/ipad 触发意外的调整大小事件【英文标题】:iphone/ipad triggering unexpected resize events 【发布时间】:2012-01-17 16:45:40 【问题描述】:

我正在开发我的网站的移动版本。我尽可能多地使用媒体查询和 CSS,但我也使用了一些 javascript,例如,在较小的设备上将我的导航变成折叠/展开列表以节省空间。

为了处理所有这些,我尝试使用 window.resize 事件。这允许在调整大小时在桌面浏览器上发生魔法,但是当我不期待它们时,我会在 iPad/iPhone 上收到调整大小事件。

在桌面浏览器上,如果我实际调整窗口大小,我只会收到调整大小事件。在移动浏览器上,当我改变方向(预期)时,我会收到 resize 事件,但当我切换到展开/折叠某些东西时,我也会收到它。

这是一个简单的例子:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<title>Resize test</title>
<style>
.box height: 10000px; background: green; display: none;
</style>
<script>
$(function()
    $(".opener").click(function()
        $(".box").slideToggle();
    );
    $(window).resize(function()
        alert("resized");
    );
);
</script>
</head>

<body>
<a href="#" class="opener">Open/close me</a>
<div class="box"></div>
</body>
</html>

当您在桌面浏览器上单击链接时,没有警报。单击 iPhone/iPad 上的链接,您会收到警报。有什么关系?

【问题讨论】:

嗨@rdoyle720。为什么不将@ 3stripe 答案标记为有效答案? @rdoyle720 我也想要 :) 也留在这里,因为它解决了我的问题:boagworld.com/dev/ios-safari-resizing-issues 【参考方案1】:

在继续使用$(window).resize 函数之前,存储窗口宽度并检查它是否确实发生了变化:

jQuery(document).ready(function($) 

    // Store the window width
    var windowWidth = $(window).width();

    // Resize Event
    $(window).resize(function()

        // Check window width has actually changed and it's not just iOS triggering a resize event on scroll
        if ($(window).width() != windowWidth) 

            // Update the window width for next time
            windowWidth = $(window).width();

            // Do stuff here

        

        // Otherwise do nothing

    );

);

【讨论】:

谢谢。我自己在这个问题上花了太长时间。非常简单的解决方案! 我喜欢这个解决方案。让滚动触发 resize 事件的 iOS 去他妈的。难以理解。 @MarcosPérezGude 这很有意义,因为它实际上是在调整视口的大小 - 由于控件和 url 栏大小的变化,您的内容会发生变化并重新渲染。有时这可能是一个特性,而不是一个错误。 2017,滚动仍被视为调整大小事件。 如果有人想检测高度的变化(不是很常见但可能发生),我建议对$(window).height()进行同样的检查【参考方案2】:

这是已接受答案的原版 javascript 版本

document.addEventListener('DOMContentLoaded', function() 

    // Store the window width
    var windowWidth = window.innerWidth

    // Resize Event
    window.addEventListener("resize", function() 

        // Check window width has actually changed and it's not just iOS triggering a resize event on scroll
        if (window.innerWidth != windowWidth) 

            // Update the window width for next time
            windowWidth = window.innerWidth

            // Do stuff here

        

        // Otherwise do nothing
    )

)

【讨论】:

这是个好主意【参考方案3】:

我需要指定宽度:

   <meta name="viewport" content="width=1000, initial-scale=1.0, user-scalable=yes">

样式:

html, body

       height:100%;
       width:100%;
       overflow:auto;

【讨论】:

谢谢,但是我失去了设计的响应部分,让它适应不同的分辨率...... 做到了,添加:html, body height: 100%;溢出:自动; margin: 0 停止了调整大小事件。 实际上不,这并没有完全解决它。 overflow: auto 让我失去了滚动的动力。如果我添加 -webkit-overflow-scrolling: touch 我会找回它,但会在弹跳时失去下面的亚麻质地。也许这是我能得到的最好的。 所以基本上这些事件是正在进入的高度大小事件。也许 iScroll 4 可以解决 scolling 问题? cubiq.org/iscroll-4 只是添加到这个.. 我有同样的问题,似乎通过改变 html & body 上的溢出,resize 事件停止触发 - 问题解决了!谢谢理查德【参考方案4】:

我在 *** 本身 ​​link of the solution 中找到了答案。 sidonaldson 的回答帮助我解决了之前遇到的类似问题。太棒了

答案是:

var cachedWidth = $(window).width();
    $(window).resize(function()
        var newWidth = $(window).width();
        if(newWidth !== cachedWidth)
            //DO RESIZE HERE
            cachedWidth = newWidth;
        
    );

【讨论】:

【参考方案5】:

假设是否错误,您只想在非触摸设备上获得调整大小事件的效果?如果是这样,您可以使用 Modernizr 并进行如下检查:

    $(window).resize(function(e)
       if(Modernizr.touch) 
         e.preventDefault();
       
    );

【讨论】:

不幸的是,Modernizr 不能再检测触摸,也不应该检测。 stucox.com/blog/you-cant-detect-a-touchscreen【参考方案6】:

检查您是否在页面加载时显式滚动 html 正文包装器以隐藏地址栏。

【讨论】:

【参考方案7】:

@3stripe 有正确答案。

这只是一个轻微的修改,通过缓存窗口对象而不是重复实例化 jQuery 来提高效率(请记住,resize 事件可能会在实际调整大小时快速调用)。

jQuery(document).ready(function($) 

    // Cached window jQuery object
    var $window = $(window);

    // Store the window width
    var windowWidth = $window.width();

    // Resize Event
    $window.resize(function()

        // Check window width has actually changed and it's not just iOS triggering a resize event on scroll
        if ($window.width() != windowWidth) 

            // Update the window width for next time
            windowWidth = $window.width();

            // Do stuff here

        

        // Otherwise do nothing

    );

);

【讨论】:

是的,这更好,但不应该是“var $window = $(window);” (您缺少 var 声明)【参考方案8】:

检查窗口大小以查看它是否已更改感觉很糟糕。相反,请使用 jQuery 为您提供的资源!

在事件处理程序中,您可以检查 jQuery 事件的 target 字段,该字段始终设置为发起事件的 DOM 元素。如果用户调整窗口大小,target 将是窗口。如果用户调整#someDiv 的大小,target 将是#someDiv

$(window).on('resize', function(event) 
    if ($(event.target).is($(window))) 
       doTheThing();
    
);

【讨论】:

你以前检查过你的答案吗?在 iOS 滚动上,它会触发 window.resize 事件(带有目标窗口),因此你不能说它是否确实调整了大小,让我们有唯一的解决方案来检查它与存储的值(但你可以优化一点并且仅对 iOS 执行此操作 - 还要检查 navigator 代理)

以上是关于iphone/ipad 触发意外的调整大小事件的主要内容,如果未能解决你的问题,请参考以下文章

移动 chrome 在滚动时触发调整大小事件

如何使用 jquery 触发一般 DOM 对象调整大小的事件

iPad不会触发从垂直到水平的调整大小事件?

javascript 节流调整大小触发的事件

如何确定移动浏览器中的软键盘是不是触发了调整大小事件?

WPF Toolkit DataGrid 列调整大小事件