【问题标题】:IFRAMEs and the Safari on the iPad, how can the user scroll the content?IFRAMEs 和 iPad 上的 Safari,用户如何滚动内容?
【发布时间】:2011-06-03 16:54:48
【问题描述】:

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

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

【问题讨论】:

标签: html ipad iframe safari scroll


【解决方案1】:

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 中工作过吗?
【解决方案2】:

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

但是,如果您无法在 iframe 内上下滚动,如下图所示,

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

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

【讨论】:

    【解决方案3】:

    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 会在下一个版本中修复这个恼人的错误。
    • 有人知道这个错误的有效来源吗?喜欢苹果的吗?
    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

      正如其他帖子中提到的,溢出的css值的组合:auto; & -webkit-overflow-scrolling: 触摸;

      适用于有问题的 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 &amp;&amp; !is_chrome; } 除此之外,您不需要函数。
      【解决方案6】:

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

      1. 没有滚动条让用户知道他们可以滚动
      2. 用户必须使用两指滚动
      3. 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>
        

      【讨论】:

        【解决方案7】:

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

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

        ma​​in.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"
        });
        

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

        【讨论】:

        • 你的 jquery 应该有逗号而不是分号。否则这似乎很好。谢谢!
        【解决方案8】:

        基于this article,我整理了以下提供一些非常基本功能的sn-p:

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

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

        【讨论】:

          【解决方案9】:

          到目前为止,当我尝试时,没有一个解决方案对我完全有效(有时,只有在二次加载时出现问题),但作为一种解决方法,使用此处描述的对象元素,然后包装在可滚动的 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 问题。

          【讨论】:

            【解决方案10】:

            问题

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

            1. 对 HTML 结构的任何更改都有可能破坏多年未触及的脚本和样式表。
            2. 手动查找和修复所有 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。

            【讨论】:

              【解决方案11】:

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

              【讨论】:

                【解决方案12】:

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

                【讨论】:

                • 不幸的是,它没有。正确答案已在上面标出。
                • 您必须同时使用这两种方式来定位新旧 iPad 或未使用最新 iOS 的用户
                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2019-04-01
                • 2015-07-31
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多