ChatGPT解决这个技术问题 Extra ChatGPT

IFRAMEs 和 iPad 上的 Safari,用户如何滚动内容?

根据 Apple iOS 的口头禅,应该可以通过用两根手指拖动来滚动 IFRAME 的内容。不幸的是,在 iPad 上运行最新版本的 iOS 我还没有找到一个使用这种方法滚动 IFRAME 的网站 - 也没有出现滚动条。

有谁知道用户应该如何使用移动 Safari 滚动 IFRAME 的内容?

我用两根手指没有问题。没有滚动条出现,但内容滚动。
请将问题迁移给超级用户,并发布一个不起作用的示例站点。我用 iPad 尝试过的每个网站都可以使用两指滚动。
它肯定不适用于最新版本的 iOS (4.2.1) 尝试 w3 站点示例:w3schools.com/tags/tryit.asp?filename=tryhtml_iframe 比较页面在 iPad 和桌面浏览器上的外观。完全不同,无法滚动。这是一个编程问题,因为它是一个需要在 IFRAME 或周围的 DIV 上设置哪些样式位才能使滚动起作用的问题。

P
Peter O.

iOS 5 添加了以下样式,可以添加到父 div 以便滚动工作。

-webkit-overflow-scrolling:touch


我发现我必须将其添加为父 div 上的样式。如果我使用 jQuery("#div").css("-webkit-overflow-scrolling","touch") 设置它,那么它实际上不起作用。此外,您现在必须将它与 overflow:auto 结合使用,这意味着您可能在某些非触摸浏览器上获得双滚动条...
以下 jQuery 糖对我有用:gist.github.com/2388015(这是非常基本的,不实现边框复制)
它可以与 iPad 上的 ChromeApp 一起使用吗?它适用于 Safari Mobile
在 iOS 7 中工作。它在你之前在 iOS 6 中工作过吗?
D
Dipin Krishnan

答案中提到的 -webkit-overflow-scrolling:touch 实际上是可能的解决方案。

<div style="overflow:scroll !important; -webkit-overflow-scrolling:touch !important;">
     <iframe src="YOUR_PAGE_URL" width="600" height="400"></iframe>
</div>

https://i.stack.imgur.com/vJiQe.png

你可以尝试像这样用两根手指对角滚动,

https://i.stack.imgur.com/8G7Hl.png

这实际上在我的情况下有效,所以如果您还没有找到解决方案,请分享它。


d
deCastongrene

iframe 似乎没有正确显示和滚动。您可以使用对象标签来替换 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>

不幸的是,这也不起作用。似乎在 4.2.1 中,两个手指 iframe 和对象滚动中断(尽管它适用于文本框)。希望 Apple 会在下一个版本中修复这个恼人的错误。
任何人如何获得此错误的有效来源?像苹果一样?
F
Foreever

这不是我的答案,但我只是从 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>

T
Toothless Seer

在其他帖子中提到,溢出的css值的组合:auto; & -webkit-溢出滚动:触摸;

适用于有问题的 iframe 及其父 div

不幸的是,双滚动条在非触摸浏览器上的副作用。

我使用的解决方案是通过 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() 被定义为跟随...

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 系统上测试 2) 未在平板电脑上的 Android 浏览器上测试,可能需要额外的更改

(所以这个解决方案可能不完整)


function isSafariBrowser() { return is_safari && !is_chrome; }除此之外您不需要函数。
H
Hammad Khan

下面的代码对我有用(感谢 Christopher Zimmermann 的博文 http://dev.magnolia-cms.com/blog/2012/05/strategies-for-the-iframe-on-the-ipad-problem/)。问题是:

没有滚动条让用户知道他们可以滚动 用户必须使用两指滚动 PDF 文件未居中(仍在处理中) 测试 iFrame在 iPad 上

这里是一些额外的内容。


D
Daniel Beck

这就是我为使 iframe 滚动在 iPad 上工作所做的工作。请注意,此解决方案仅在您控制 iframe 内显示的 html 时才有效。

它实际上关闭了默认的 iframe 滚动,而是导致 iframe 内的 body 标签滚动。

主.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>

测试.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"
});

我使用这个解决方案让 TinyMCE(wordpress 编辑器)在 iPad 上正确滚动。


你的 jquery 应该有逗号而不是分号。否则这似乎很好。谢谢!
p
periklis

基于 this article,我整理了以下提供一些非常基本功能的代码段:

<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>

显然它远非完美(考虑到它实际上将您的页面高度扩展到无穷大),但这是迄今为止我发现的唯一可行的解决方法。


P
Philipp Lenssen

到目前为止,当我尝试时,没有一个解决方案对我完全有效(有时,只有二次加载有问题),但作为一种解决方法,使用这里描述的对象元素,然后包装在一个可滚动的 div 中,然后将对象设置为非常高(5000px)为我完成了这项工作。这是一个很大的解决方法,但效果不太好(对于初学者来说,超过 5000 像素的页面会导致问题——尽管 10000 像素对我来说完全破坏了它)但它似乎在我的一些测试用例中完成了工作:

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>';
}

希望 Apple 能够修复 Safari iFrame 问题。


C
Community

问题

我帮助维护一个庞大、复杂、凌乱的旧站点,其中所有内容(字面意思)都嵌套在多个 iframe 级别中——其中许多是动态创建的和/或具有动态 src。这带来了以下挑战:

对 HTML 结构的任何更改都有可能破坏多年未触及的脚本和样式表。手动查找和修复所有 iframe 和 src 文档会花费太多时间和精力。

在迄今为止发布的解决方案中,this 是我见过的唯一一个克服挑战 1 的解决方案。不幸的是,它似乎不适用于某些 iframe,而且当它运行时,滚动非常有问题(这似乎导致页面上的其他错误,例如无响应的链接和表单控件)。

解决方案

如果以上听起来像您的情况,您可能想尝试以下脚本。它放弃了原生滚动,而是让所有 iframe 在其视口范围内可拖动。您只需要将其添加到包含顶级 iframe 的文档中;它将根据需要将修复应用于他们及其后代。

这是一个有效的 fiddle*,下面是代码:

(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 为测试目的启用了鼠标支持。在生产站点上,您需要设置 mouse=false。


c
ccs

经过一番苦恼后,我发现了如何在 ipad 上滚动 iframe。秘诀是在 iframe 区域的左侧(可能稍微超出边界)进行垂直手指滑动(单指即可)。在笔记本电脑或 PC 上,滚动条在右侧,所以自然而然地,我在 ipad 上花了很多时间来试验右侧的手指动作。只有当我尝试左侧时,iframe 才会滚动。


s
ske57

overflow: auto; 添加到样式中,两指滚动应该可以工作。


不幸的是,事实并非如此。正确答案在上面标出。
您必须同时使用两者来定位较旧和较新的 iPad 或未使用最新 iOS 的人