有人在移动safari中处理过iframes吗?有什么想法可以开始吗?
没错,你无法通过设置iframe的高度和宽度来限制其大小。你需要将其放入一个div中。如果你控制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破坏了我们的解决方案。我一直在尝试找到一个新的解决方法,但还没有成功。另外,由于引入了Remote Web Inspector,需要Mac才能使用,因此不再可能在设备上调试javascript。
overflow: auto
引起的,请在这里查看 https://dev59.com/TWkw5IYBdhLWcg3w4eiS#9585204 - TecHunter仅当您控制外部页面和 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
成为可滚动节点即可。
如果 iFrame 的内容不是你自己的,则下面的解决方案将不起作用。
对于 Android,你只需要将 iFrame 包裹在一个 DIV 中,并将该 DIV 的高度设置为 document.documentElement.clientHeight。然而,iOS 则是另外一回事。虽然我还没有尝试 Sharon 的解决方案,但它似乎是一个好的解决方案。我找到了一个更简单的解决方案,但它仅适用于 iOS 5.+。
将 iframe 元素包裹在一个 DIV 中(假设我们称其为 scroller),设置 DIV 的高度,并确保新 DIV 具有以下样式:
$('#scroller').css({'overflow' : 'auto', '-webkit-overflow-scrolling' : 'touch'});
这个方法可以生效,但你会发现在大多数实现中,当滚动时iframe中的内容会变空,基本上就无法使用了。据我了解,这个问题早在iOS 5.0时就被报告给Apple作为一个bug。为了绕过这个问题,在iframe中找到body元素并添加-webkit-transform','translate3d(0, 0, 0)即可:
$('#contentIframe').contents().find('body').css('-webkit-transform', 'translate3d(0, 0, 0)');
如果你的应用程序或iframe占用了大量内存,可能会出现卡顿的滚动条,这时你可能需要使用Sharon的解决方案。
我将@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>
<div id="scroller" style="height: 400px; width: 100%; overflow: auto;">
<iframe height="100%" id="iframe" scrolling="no" width="100%" src="url" />
</div>
Sharon的方法对我很有效,但是当在iframe中跟随链接并按下浏览器返回按钮时,会加载页面的缓存版本,而iframe不再可滚动。为了克服这个问题,我使用了一些代码来刷新页面,如下所示:
if ('ontouchstart' in document.documentElement)
{
document.getElementById('Scrolling').src = document.getElementById('SCrolling').src;
}
我已经实现了以下功能,并且它工作良好。基本上,我根据 iFrame 内容的大小设置了 body 的尺寸。这意味着我们的非 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';
});
}
不要滚动IFrame页面或其内容,而是滚动父页面。如果您控制IFrame内容,则可以使用iframe-resizer库将iframe元素本身转换为适当的块级元素,并具有自然/正确/本地高度。此外,请勿尝试在父页面中定位(固定,绝对)您的iframe,或在模态窗口中呈现iframe,特别是如果它具有表单元素。
我还怀疑iOS Safari具有非标准行为,会将您的iframe高度扩展到其自然高度,就像桌面浏览器将使用iframe-resizer库一样,这些浏览器似乎会将响应式iframe内容呈现为高度0px或150px或其他不实用的默认值。如果需要限制宽度,请在iframe内部尝试max-width样式。
纯粹使用 MSchimpf 和 Ahmad 的代码,我进行了调整,以便将 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 -->
解决方案是在iframe上使用Scrolling =“no”
。
就是这样。