IFRAME和iPad上的Safari,用户如何滚动内容?
根据苹果iOS的口头禅,应该可以通过用两根手指来拖动IFRAME的内容。 不幸的是,在iPad上运行iOS的最新版本,我还没有find一个网站的IFRAME滚动使用这种方法 – 没有滚动条出现。
有谁知道如何用户应该滚动移动Safari的IFRAME的内容?
iOS 5添加了以下样式,可以添加到父div,以便滚动。
-webkit-overflow-scrolling:touch
-webkit-overflow-scrolling:touch
在答案中提到的事实上是可能的解决scheme。
<div style="overflow:scroll !important; -webkit-overflow-scrolling:touch !important;"> <iframe src="YOUR_PAGE_URL" width="600" height="400"></iframe> </div>
但是,如果您无法在iframe中上下滚动,如下图所示,
你可以尝试像这样对angular地用2个手指滚动,
这实际上在我的情况下工作,所以只是分享它,如果你还没有find一个解决scheme。
不会出现iframe显示和正确滚动。 您可以使用一个对象标签来replace一个iframe,内容可以用2个手指来滚动。 这是一个简单的例子:
<html> <head> <meta name="viewport" content="minimum-scale=1.0; maximum-scale=1.0; user-scalable=false; initial-scale=1.0;"/> </head> <body> <div>HEADER - use 2 fingers to scroll contents:</div> <div id="scrollee" style="height:75%;" > <object id="object" height="90%" width="100%" type="text/html" data="http://en.wikipedia.org/"></object> </div> <div>FOOTER</div> </body> </html>
这不是我的答案,但我只是从https://gist.github.com/anonymous/2388015复制它,只是因为答案是可怕的,并完全解决了这个问题。; 信用完全交给匿名作者。
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> <script type="text/javascript"> $(function(){ if (/iPhone|iPod|iPad/.test(navigator.userAgent)) $('iframe').wrap(function(){ var $this = $(this); return $('<div />').css({ width: $this.attr('width'), height: $this.attr('height'), overflow: 'auto', '-webkit-overflow-scrolling': 'touch' }); }); }) </script>
正如其他文章中提到的,溢出的css值的组合:auto; &-webkit-overflow-scrolling:touch;
适用于有问题的iframe和其父母div的作品
在非触摸式浏览器上使用双滚动条的不幸的副作用。
我使用的解决scheme是通过JavaScript / jQuery添加这些CSS值。 这使我可以为所有浏览器使用基本的CSS
if (isSafariBrowser()){ $('#parentDivID').css('overflow', 'auto'); $('#parentDivID').css('-webkit-overflow-scrolling', 'touch'); $('#iframeID').css('overflow', 'auto'); $('#iframeID').css('-webkit-overflow-scrolling', 'touch'); }
isSafariBrowser()被定义为foll …
var is_chrome = navigator.userAgent.indexOf('Chrome') > -1; var is_safari = navigator.userAgent.indexOf("Safari") > -1; function isSafariBrowser(){ if (is_safari){ if (is_chrome) // Chrome seems to have both Chrome and Safari userAgents return false; else return true; } return false; }
这允许我的应用程序在iPad上工作注1)未在其他ios系统上testing2)没有在平板电脑上的Android浏览器上testing过,可能需要额外的更改
(所以这个解决scheme可能不完整)
下面的代码适用于我(感谢Christopher Zimmermann的博客文章http://dev.magnolia-cms.com/blog/2012/05/strategies-for-the-iframe-on-the-ipad-problem/ ) 。 问题是:
- 没有滚动条让用户知道他们可以滚动
- 用户必须使用双指滚动
-
PDF文件不居中(仍在工作)
<!DOCTYPE HTML> <html> <head> <title>Testing iFrames on iPad</title> <style> div { border: solid 1px green; height:100px; } .scroller{ border:solid 1px #66AA66; height: 400px; width: 400px; overflow: auto; text-align:center; } </style>
<table> <tr> <td><div class="scroller"> <iframe width="400" height="400" src="http://www.supremecourt.gov/opinions/11pdf/11-393c3a2.pdf" ></iframe> </div> </td> <td><div class="scroller"> <iframe width="400" height="400" src="http://www.supremecourt.gov/opinions/11pdf/11-393c3a2.pdf" ></iframe> </div> </td> </tr> <tr> <td><div class="scroller"> <iframe width="400" height="400" src="http://www.supremecourt.gov/opinions/11pdf/11-393c3a2.pdf" ></iframe> </div> </td> <td><div class="scroller"> <iframe width="400" height="400" src="http://www.supremecourt.gov/opinions/11pdf/11-393c3a2.pdf" ></iframe> </div> </td> </tr> </table> <div> Here are some additional contents.</div>
这就是我所做的,以获得iframe滚动iPad的工作。 请注意,此解决scheme只有在您控制iframe中显示的html时才有效。
它实际上closures了默认的iframe滚动,而是使iframe内的body标签滚动。
main.html :
<!DOCTYPE html> <html> <head> <style type="text/css"> #container { position: absolute; top: 50px; left: 50px; width: 400px; height: 300px; overflow: hidden; } #iframe { width: 400px; height: 300px; } </style> </head> <body> <div id="container"> <iframe src="test.html" id="iframe" scrolling="no"></iframe> </div> </body> </html>
test.html :
<!DOCTYPE html> <html> <head> <style type="text/css"> html { overflow: auto; -webkit-overflow-scrolling: touch; } body { height: 100%; overflow: auto; -webkit-overflow-scrolling: touch; margin: 0; padding: 8px; } </style> </head> <body> … </body> </html>
如果您愿意,也可以使用jQuery来完成:
$("#iframe").contents().find("body").css({ "height": "100%", "overflow": "auto", "-webkit-overflow-scrolling": "touch" });
我用这个解决scheme让TinyMCE(WordPress的编辑器)在iPad上正确滚动。
基于这篇文章 ,我将下面的代码片段放在一起,提供了一些非常基本的function:
<div id = "container"></div> <script> function setPDFHeight(){ $("#pdfObject")[0].height = $("#pdfObject")[0].offsetHeight; } $('#container').append('<div align="center" style="width: 100%; height:100%; overflow: auto !important; -webkit-overflow-scrolling: touch !important;">\ <object id="pdfObject" width="100%" height="1000000000000" align="center" data="content/lessons/12/t.pdf" type="application/pdf" onload="setPDFHeight()">You have no plugin installed</object></div>'); </script>
显然,它远非完美(鉴于它实际上将页面高度扩展到无穷大),但它是迄今为止唯一可行的解决方法。
到目前为止,我尝试过的解决scheme中没有一个完全适用于我(有时候,只有次级加载时有bug),但是作为解决方法,使用如此处所述的对象元素,然后将其包装在可滚动的div中,然后将对象设置为非常高度(5000px)为我做了这份工作。 这是一个很大的解决方法,并不能令人难以置信地工作(对于初学者来说,超过5000像素的页面会导致问题 – 但是10000px完全破坏了它),但似乎在我的一些testing用例中完成了这项工作:
var style = 'left: ...px; top: ...px; ' + 'width: ...px; height: ...px; border: ...'; if (isIOs) { style += '; overflow: scroll !important; -webkit-overflow-scrolling: touch !important;'; html = '<div style="' + style + '">' + '<object type="text/html" data="http://example.com" ' + 'style="width: 100%; height: 5000px;"></object>' + '</div>'; } else { style += '; overflow: auto;'; html = '<iframe src="http://example.com" ' + 'style="' + style + '"></iframe>'; }
希望苹果能够解决Safari iFrame问题。
问题
我帮助维护一个大的,复杂的,凌乱的旧网站,其中一切 (字面上)嵌套在多个层次的iframe中 – 其中许多是dynamic创build的和/或具有dynamicsrc。 这造成了以下挑战:
- 对HTML结构的任何更改都有可能会破坏多年未触及的脚本和样式表。
- 手动查找并修复所有的iframe和src文件将花费太多的时间和精力。
到目前为止发布的解决scheme中, 这是我见过的唯一一个克服了挑战1的问题。不幸的是,它似乎并不适用于某些iframe,当它出现时,滚动非常糟糕(这似乎会导致其他页面上的错误,如无响应的链接和表单控件)。
解决scheme
如果上述听起来像你的情况,你可能想要尝试下面的脚本。 它放弃原生滚动,而是使所有的内联框架在其视口范围内可拖动。 您只需将其添加到包含顶级iframe的文档; 它将根据需要将修补应用于他们及其后代。
这里有一个工作小提琴 *,这是代码:
(function() { var mouse = false //Set mouse=true to enable mouse support , iOS = /iPad|iPhone|iPod/.test(navigator.platform); if(mouse || iOS) { (function() { var currentFrame , startEvent, moveEvent, endEvent , screenY, translateY, minY, maxY , matrixPrefix, matrixSuffix , matrixRegex = /(.*([\.\d-]+, ?){5,13})([\.\d-]+)(.*)/ , min = Math.min, max = Math.max , topWin = window; if(!iOS) { startEvent = 'mousedown'; moveEvent = 'mousemove'; endEvent = 'mouseup'; } else { startEvent = 'touchstart'; moveEvent = 'touchmove'; endEvent = 'touchend'; } setInterval(scrollFix, 500); function scrollFix() {fixSubframes(topWin.frames);} function fixSubframes(wins) {for(var i = wins.length; i; addListeners(wins[--i]));} function addListeners(win) { try { var doc = win.document; if(!doc.draggableframe) { win.addEventListener('unload', resetFrame); doc.draggableframe = true; doc.addEventListener(startEvent, touchStart); doc.addEventListener(moveEvent, touchMove); doc.addEventListener(endEvent, touchEnd); } fixSubframes(win.frames); } catch(e) {} } function resetFrame(e) { var doc = e.target , win = doc.defaultView , iframe = win.frameElement , style = getComputedStyle(iframe).transform; if(iframe===currentFrame) currentFrame = null; win.removeEventListener('unload', resetFrame); doc.removeEventListener(startEvent, touchStart); doc.removeEventListener(moveEvent, touchMove); doc.removeEventListener(endEvent, touchEnd); if(style !== 'none') { style = style.replace(matrixRegex, '$1|$3|$4').split('|'); iframe.style.transform = style[0] + 0 + style[2]; } else iframe.style.transform = null; iframe.style.WebkitClipPath = null; iframe.style.clipPath = null; delete doc.draggableiframe; } function touchStart(e) { var iframe, style, offset, coords , touch = e.touches ? e.touches[0] : e , elem = touch.target , tag = elem.tagName; currentFrame = null; if(tag==='TEXTAREA' || tag==='SELECT' || tag==='HTML') return; for(;elem.parentElement; elem = elem.parentElement) { if(elem.scrollHeight > elem.clientHeight) { style = getComputedStyle(elem).overflowY; if(style==='auto' || style==='scroll') return; } } elem = elem.ownerDocument.body; iframe = elem.ownerDocument.defaultView.frameElement; coords = getComputedViewportY(elem.clientHeight < iframe.clientHeight ? elem : iframe); if(coords.elemTop >= coords.top && coords.elemBottom <= coords.bottom) return; style = getComputedStyle(iframe).transform; if(style !== 'none') { style = style.replace(matrixRegex, '$1|$3|$4').split('|'); matrixPrefix = style[0]; matrixSuffix = style[2]; offset = parseFloat(style[1]); } else { matrixPrefix = 'matrix(1, 0, 0, 1, 0, '; matrixSuffix = ')'; offset = 0; } translateY = offset; minY = min(0, offset - (coords.elemBottom - coords.bottom)); maxY = max(0, offset + (coords.top - coords.elemTop)); screenY = touch.screenY; currentFrame = iframe; } function touchMove(e) { var touch, style; if(currentFrame) { touch = e.touches ? e.touches[0] : e; style = min(maxY, max(minY, translateY + (touch.screenY - screenY))); if(style===translateY) return; e.preventDefault(); currentFrame.contentWindow.getSelection().removeAllRanges(); translateY = style; currentFrame.style.transform = matrixPrefix + style + matrixSuffix; style = 'inset(' + (-style) + 'px 0px ' + style + 'px 0px)'; currentFrame.style.WebkitClipPath = style; currentFrame.style.clipPath = style; screenY = touch.screenY; } } function touchEnd() {currentFrame = null;} function getComputedViewportY(elem) { var style, offset , doc = elem.ownerDocument , bod = doc.body , elemTop = elem.getBoundingClientRect().top + elem.clientTop , elemBottom = elem.clientHeight , viewportTop = elemTop , viewportBottom = elemBottom + elemTop , position = getComputedStyle(elem).position; try { while(true) { if(elem === bod || position === 'fixed') { if(doc.defaultView.frameElement) { elem = doc.defaultView.frameElement; position = getComputedStyle(elem).position; offset = elem.getBoundingClientRect().top + elem.clientTop; viewportTop += offset; viewportBottom = min(viewportBottom + offset, elem.clientHeight + offset); elemTop += offset; doc = elem.ownerDocument; bod = doc.body; continue; } else break; } else { if(position === 'absolute') { elem = elem.offsetParent; style = getComputedStyle(elem); position = style.position; if(position === 'static') continue; } else { elem = elem.parentElement; style = getComputedStyle(elem); position = style.position; } if(style.overflowY !== 'visible') { offset = elem.getBoundingClientRect().top + elem.clientTop; viewportTop = max(viewportTop, offset); viewportBottom = min(viewportBottom, elem.clientHeight + offset); } } } } catch(e) {} return { top: max(viewportTop, 0) ,bottom: min(viewportBottom, doc.defaultView.innerHeight) ,elemTop: elemTop ,elemBottom: elemBottom + elemTop }; } })(); } })();
* jsfiddle启用了鼠标支持以进行testing。 在生产网站上,您需要设置mouse = false。
经过多次恶化之后,我发现了如何在我的ipad上滚动iframe。 秘密是在iframe区域的左边(也许稍微在边界之外)做垂直手指轻扫(单指细)。 在笔记本电脑或个人电脑上,滚动条在右侧,所以当然,我花了很多时间在我的ipad上尝试右手边的手指动作。 只有当我尝试左侧的IFRAME滚动。
添加overflow: auto;
风格和双指滚动应该工作。