如何在 mobile safari 中正确显示 iFrame

发布于 2024-10-21 02:42:53 字数 186 浏览 3 评论 0原文

我尝试在移动 Web 应用程序中显示 iframe,但无法将 iframe 的大小限制为 iPhone 屏幕的尺寸。奇怪的是,iframe 元素上的高度和宽度属性似乎没有任何效果。用 div 包围它可以限制它,但我无法在 iframe 内滚动。

之前有人解决过 mobile safari 中的 iframe 问题吗?有什么想法从哪里开始吗?

I'm trying to display an iframe in my mobile web application, but I'm having trouble restricting the size of the iframe to the dimensions of the iPhone screen. The height and width attributes on the iframe element seem to have no effect, strangely. Surrounding it with a div manages to constrain it, but then I'm unable to scroll within the iframe.

Has anyone tackled iframes in mobile safari before? Any ideas where to start?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

看轻我的陪伴 2024-10-28 02:42:54

如果 iFrame 内容不是您的,那么下面的解决方案将不起作用。

对于 Android,您所需要做的就是用 DIV 包围 iframe,并将 div 的高度设置为 document.documentElement.clientHeight。然而,IOS 却是另一种动物。虽然我还没有尝试过莎伦的解决方案,但它看起来确实是一个很好的解决方案。我确实找到了一个更简单的解决方案,但它仅适用于 IOS 5.+。

用 DIV 包围您的 iframe 元素(我们称其为滚动条),设置 DIV 的高度并确保新的 DIV 具有以下样式:

$('#scroller').css({'overflow' : 'auto', '-webkit-overflow-scrolling' : 'touch'});

仅此一项即可工作,但您会注意到在大多数实现中,iframe 中的内容会变为滚动时为空白,基本上无用。我的理解是,早在 iOS 5.0 中,这种行为就已作为 bug 报告给 Apple。要解决这个问题,请在 iframe 中找到 body 元素并添加 -webkit-transform', 'translate3d(0, 0, 0) ,如下所示:

$('#contentIframe').contents().find('body').css('-webkit-transform', 'translate3d(0, 0, 0)');

如果您的应用程序或 iframe 内存使用量很大,您可能会遇到滚动问题您可能需要使用莎伦的解决方案。

If the iFrame content is not yours then the solution below will not work.

With Android all you need to do is to surround the iframe with a DIV and set the height on the div to document.documentElement.clientHeight. IOS, however, is a different animal. Although I have not yet tried Sharon's solution it does seem like a good solution. I did find a simpler solution but it only works with IOS 5.+.

Surround your iframe element with a DIV (lets call it scroller), set the height of the DIV and make sure that the new DIV has the following styling:

$('#scroller').css({'overflow' : 'auto', '-webkit-overflow-scrolling' : 'touch'});

This alone will work but you will notice that in most implementations the content in the iframe goes blank when scrolling and is basically rendered useless. My understanding is that this behavior has been reported as a bug to Apple as early as iOS 5.0. To get around that problem, find the body element in the iframe and add -webkit-transform', 'translate3d(0, 0, 0) like so:

$('#contentIframe').contents().find('body').css('-webkit-transform', 'translate3d(0, 0, 0)');

If your app or iframe is heavy on memory usage you might get a hitchy scroll for which you might need to use Sharon's solution.

无人问我粥可暖 2024-10-28 02:42:54

我已将 @Sharon 的代码放在一起,如下所示,它适用于我在 iPad 上用两指滚动的情况。要使其正常工作,您唯一需要更改的是 iframe 上的 src 属性(我使用了 PDF 文档)。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Pdf Scrolling in mobile Safari</title>
</head>
<body>
<div id="scroller" style="height: 400px; width: 100%; overflow: auto;">
<iframe height="100%" id="iframe" scrolling="no" width="100%" id="iframe" src="data/testdocument.pdf" />
</div>
<script type="text/javascript">
    setTimeout(function () {
        var startY = 0;
        var startX = 0;
        var b = document.body;
        b.addEventListener('touchstart', function (event) {
            parent.window.scrollTo(0, 1);
            startY = event.targetTouches[0].pageY;
            startX = event.targetTouches[0].pageX;
        });
        b.addEventListener('touchmove', function (event) {
            event.preventDefault();
            var posy = event.targetTouches[0].pageY;
            var h = parent.document.getElementById("scroller");
            var sty = h.scrollTop;

            var posx = event.targetTouches[0].pageX;
            var stx = h.scrollLeft;
            h.scrollTop = sty - (posy - startY);
            h.scrollLeft = stx - (posx - startX);
            startY = posy;
            startX = posx;
        });
    }, 1000);
    </script>
</body>
</html>

I have put @Sharon's code together into the following, which works for me on the iPad with two-finger scrolling. The only thing you should have to change to get it working is the src attribute on the iframe (I used a PDF document).

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Pdf Scrolling in mobile Safari</title>
</head>
<body>
<div id="scroller" style="height: 400px; width: 100%; overflow: auto;">
<iframe height="100%" id="iframe" scrolling="no" width="100%" id="iframe" src="data/testdocument.pdf" />
</div>
<script type="text/javascript">
    setTimeout(function () {
        var startY = 0;
        var startX = 0;
        var b = document.body;
        b.addEventListener('touchstart', function (event) {
            parent.window.scrollTo(0, 1);
            startY = event.targetTouches[0].pageY;
            startX = event.targetTouches[0].pageX;
        });
        b.addEventListener('touchmove', function (event) {
            event.preventDefault();
            var posy = event.targetTouches[0].pageY;
            var h = parent.document.getElementById("scroller");
            var sty = h.scrollTop;

            var posx = event.targetTouches[0].pageX;
            var stx = h.scrollLeft;
            h.scrollTop = sty - (posy - startY);
            h.scrollLeft = stx - (posx - startX);
            startY = posy;
            startX = posx;
        });
    }, 1000);
    </script>
</body>
</html>
━╋う一瞬間旳綻放 2024-10-28 02:42:54
<div id="scroller" style="height: 400px; width: 100%; overflow: auto;">
<iframe height="100%" id="iframe" scrolling="no" width="100%" src="url" />
</div>

我正在构建我的第一个网站,这帮助我使该网站适用于我使用 iframe 嵌入的所有网站。

谢谢!

<div id="scroller" style="height: 400px; width: 100%; overflow: auto;">
<iframe height="100%" id="iframe" scrolling="no" width="100%" src="url" />
</div>

I'm building my first site and this helped me get this working for all sites that I use iframe embededding for.

Thanks!

风柔一江水 2024-10-28 02:42:54

Sharon 的方法对我有用,但是当点击 iframe 中的链接然后按下浏览器后退按钮时,会加载页面的缓存版本,并且 iframe 不再可滚动。为了克服这个问题,我使用了一些代码来刷新页面,如下所示:

if ('ontouchstart' in document.documentElement)
     {
        document.getElementById('Scrolling').src = document.getElementById('SCrolling').src;
    }

Sharon's method worked for me, however when a link in the iframe is followed and then the browser back button is pressed, the cached version of the page is loaded and the iframe is no longer scrollable. To overcome this I used some code to refresh the page as follows:

if ('ontouchstart' in document.documentElement)
     {
        document.getElementById('Scrolling').src = document.getElementById('SCrolling').src;
    }
总以为 2024-10-28 02:42:54

我实施了以下内容并且效果很好。基本上,我根据 iFrame 内容的大小设置正文尺寸。这确实意味着我们的非 iFrame 菜单可以滚动到屏幕之外,但除此之外,这使得我们的网站可以在 iPad 和 iPhone 上运行。 “workbox”是我们的 iFrame 的 ID。

// Configure for scrolling peculiarities of iPad and iPhone

if (navigator.userAgent.indexOf('iPhone') != -1 || navigator.userAgent.indexOf('iPad') != -1)
{
    document.body.style.width = "100%";
    document.body.style.height = "100%";
    $("#workbox").load(function (){ // Wait until iFrame content is loaded before checking dimensions of the content
        iframeWidth = $("#workbox").contents().width();
        if (iframeWidth > 400)
           document.body.style.width = (iframeWidth + 182) + 'px';

        iframeHeight = $("#workbox").contents().height();
        if (iframeHeight>200)
            document.body.style.height = iframeHeight + 'px';
     });
}

I implemented the following and it works well. Basically, I set the body dimensions according to the size of the iFrame content. It does mean that our non-iFrame menu can be scrolled off the screen, but otherwise, this makes our sites functional with iPad and iPhone. "workbox" is the ID of our iFrame.

// Configure for scrolling peculiarities of iPad and iPhone

if (navigator.userAgent.indexOf('iPhone') != -1 || navigator.userAgent.indexOf('iPad') != -1)
{
    document.body.style.width = "100%";
    document.body.style.height = "100%";
    $("#workbox").load(function (){ // Wait until iFrame content is loaded before checking dimensions of the content
        iframeWidth = $("#workbox").contents().width();
        if (iframeWidth > 400)
           document.body.style.width = (iframeWidth + 182) + 'px';

        iframeHeight = $("#workbox").contents().height();
        if (iframeHeight>200)
            document.body.style.height = iframeHeight + 'px';
     });
}
野鹿林 2024-10-28 02:42:54

纯粹使用 MSchimpf 和 A​​hmad 的代码,我进行了调整,以便可以将 iframe 放在 div 中,从而在页面上保留用于后退按钮和品牌的页眉和页脚。更新的代码:

<script type="text/javascript">
    $("#webview").bind('pagebeforeshow', function(event){
        $("#iframe").attr('src',cwebview);
    });

    if (navigator.userAgent.indexOf('iPhone') != -1 || navigator.userAgent.indexOf('iPad') != -1)
    {
        $("#webview-content").css("width","100%");
        $("#webview-content").css("height","100%");
        $("#iframe").load(function (){ // Wait until iFrame content is loaded before checking dimensions of the content
            iframeWidth = $("#iframe").contents().width();
            if (iframeWidth > 400)
               $("#webview-content").css("width",(iframeWidth + 182) + 'px');

            iframeHeight = $("#iframe").contents().height();
            if (iframeHeight>200)
                $("#webview-content").css("height",iframeHeight + 'px');
         });
    }       
</script>  

和html

<div class="header" data-role="header" data-position="fixed">
</div>

<div id="webview-content" data-role="content" style="height:380px;">
    <iframe id="iframe"></iframe>   
</div><!-- /content -->

<div class="footer" data-role="footer" data-position="fixed">
</div><!-- /footer -->   

Purely using MSchimpf and Ahmad's code, I made adjustments so I could have the iframe within a div, therefore keeping a header and footer for back button and branding on my page. Updated code:

<script type="text/javascript">
    $("#webview").bind('pagebeforeshow', function(event){
        $("#iframe").attr('src',cwebview);
    });

    if (navigator.userAgent.indexOf('iPhone') != -1 || navigator.userAgent.indexOf('iPad') != -1)
    {
        $("#webview-content").css("width","100%");
        $("#webview-content").css("height","100%");
        $("#iframe").load(function (){ // Wait until iFrame content is loaded before checking dimensions of the content
            iframeWidth = $("#iframe").contents().width();
            if (iframeWidth > 400)
               $("#webview-content").css("width",(iframeWidth + 182) + 'px');

            iframeHeight = $("#iframe").contents().height();
            if (iframeHeight>200)
                $("#webview-content").css("height",iframeHeight + 'px');
         });
    }       
</script>  

and the html

<div class="header" data-role="header" data-position="fixed">
</div>

<div id="webview-content" data-role="content" style="height:380px;">
    <iframe id="iframe"></iframe>   
</div><!-- /content -->

<div class="footer" data-role="footer" data-position="fixed">
</div><!-- /footer -->   
你爱我像她 2024-10-28 02:42:54

不要滚动 IFrame 页面或其内容,而是滚动父页面。如果您控制 IFrame 内容,则可以使用 iframe-resizer 库来转动 iframe 元素本身进入适当的块级元素,具有自然/正确/原生高度。另外,不要尝试将 iframe 定位(固定、绝对)在父页面中,或在模式窗口中显示 iframe,尤其是当它具有表单元素时。

我还怀疑 iOS Safari 有一种非标准行为,它将 iframe 的高度扩展到其自然高度,就像 iframe-resizer 库对桌面浏览器所做的那样,它似乎以 0px 或 150px 或其他高度渲染响应式 iframe 内容默认值没有用。如果需要限制宽度,请尝试 iframe 内的 max-width 样式。

Don't scroll the IFrame page or its content, scroll the parent page. If you control the IFrame content, you can use the iframe-resizer library to turn the iframe element itself into a proper block level element, with a natural/correct/native height. Also, don't attempt to position (fixed, absolute) your iframe in the parent page, or present an iframe in a modal window, especially if it has form elements.

I also suspect that iOS Safari has a non-standards behavior that expands your iframe's height to its natural height, much like the iframe-resizer library will do for desktop browsers, which seem to render responsive iframe content at height 0px or 150px or some other not useful default. If you need to contrain width, try a max-width style inside the iframe.

终难愈 2024-10-28 02:42:54

解决方案是在 iframe 上使用 Scrolling="no"

就是这样。

The solution is to use Scrolling="no" on the iframe.

That's it.

末骤雨初歇 2024-10-28 02:42:53

是的,你不能用高度和宽度来约束 iframe 本身。你应该在它周围放一个div。如果你控制iframe中的内容,你可以在iframe内容中放置一些JS,告诉父级在收到触摸事件时滚动div。

像这样:

JS:

setTimeout(function () {
var startY = 0;
var startX = 0;
var b = document.body;
b.addEventListener('touchstart', function (event) {
    parent.window.scrollTo(0, 1);
    startY = event.targetTouches[0].pageY;
    startX = event.targetTouches[0].pageX;
});
b.addEventListener('touchmove', function (event) {
    event.preventDefault();
    var posy = event.targetTouches[0].pageY;
    var h = parent.document.getElementById("scroller");
    var sty = h.scrollTop;

    var posx = event.targetTouches[0].pageX;
    var stx = h.scrollLeft;
    h.scrollTop = sty - (posy - startY);
    h.scrollLeft = stx - (posx - startX);
    startY = posy;
    startX = posx;
});
}, 1000);

HTML:

<div id="scroller" style="height: 400px; width: 100%; overflow: auto;">
<iframe height="100%" id="iframe" scrolling="no" width="100%" id="iframe" src="url" />
</div>

如果您不控制 iframe 内容,您可以以类似的方式在 iframe 上使用覆盖层,但是除了滚动之外,您无法与 iframe 内容进行交互 - 所以例如,您无法单击 iframe 中的链接。

过去,您可以使用两根手指在 iframe 内滚动,但现在不再起作用了。

更新:iOS 6 破坏了我们的这个解决方案。我一直在尝试为其找到新的修复程序,但还没有任何效果。此外,由于引入了需要 Mac 才能使用的 Remote Web Inspector,因此无法再在设备上调试 javascript。

Yeah, you can't constrain the iframe itself with height and width. You should put a div around it. If you control the content in the iframe, you can put some JS within the iframe content that will tell the parent to scroll the div when the touch event is received.

like this:

The JS:

setTimeout(function () {
var startY = 0;
var startX = 0;
var b = document.body;
b.addEventListener('touchstart', function (event) {
    parent.window.scrollTo(0, 1);
    startY = event.targetTouches[0].pageY;
    startX = event.targetTouches[0].pageX;
});
b.addEventListener('touchmove', function (event) {
    event.preventDefault();
    var posy = event.targetTouches[0].pageY;
    var h = parent.document.getElementById("scroller");
    var sty = h.scrollTop;

    var posx = event.targetTouches[0].pageX;
    var stx = h.scrollLeft;
    h.scrollTop = sty - (posy - startY);
    h.scrollLeft = stx - (posx - startX);
    startY = posy;
    startX = posx;
});
}, 1000);

The HTML:

<div id="scroller" style="height: 400px; width: 100%; overflow: auto;">
<iframe height="100%" id="iframe" scrolling="no" width="100%" id="iframe" src="url" />
</div>

If you don't control the iframe content, you can use an overlay over the iframe in a similar manner, but then you can't interact with the iframe contents other than to scroll it - so you can't, for example, click links in the iframe.

It used to be that you could use two fingers to scroll within an iframe, but that doesn't work anymore.

Update: iOS 6 broke this solution for us. I've been attempting to get a new fix for it, but nothing has worked yet. In addition, it is no longer possible to debug javascript on the device since they introduced Remote Web Inspector, which requires a Mac to use.

埖埖迣鎅 2024-10-28 02:42:53

仅当您同时控制外部页面和 iframe 页面时,此功能才有效。

在外部页面上,使 iframe 不可滚动。

<iframe src="" height=200 scrolling=no></iframe>

在 iframe 页面上,添加此内容。

<!doctype html>
...
<style>
html, body {height:100%; overflow:hidden}
body {overflow:auto; -webkit-overflow-scrolling:touch}
</style>

这是可行的,因为现代浏览器使用 html 来确定高度,所以我们只需给它一个固定的高度,并将 body 转换为可滚动节点。

This only works if you control both the outside page and the iframe page.

On the outside page, make the iframe unscrollable.

<iframe src="" height=200 scrolling=no></iframe>

On the iframe page, add this.

<!doctype html>
...
<style>
html, body {height:100%; overflow:hidden}
body {overflow:auto; -webkit-overflow-scrolling:touch}
</style>

This works because modern browsers uses html to determine the height, so we just give that a fixed height and turn the body into a scrollable node.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文