programing

모바일 사파리에서 iFrame을 올바르게 표시하는 방법

projobs 2021. 1. 16. 09:12
반응형

모바일 사파리에서 iFrame을 올바르게 표시하는 방법


모바일 웹 애플리케이션에 iframe을 표시하려고하는데 iframe 크기를 iPhone 화면 크기로 제한하는 데 문제가 있습니다. 이상하게도 iframe 요소의 높이 및 너비 속성이 효과가없는 것 같습니다. div로 둘러싸면 제한 할 수 있지만 iframe 내에서 스크롤 할 수 없습니다.

전에 모바일 사파리에서 iframe을 다루었던 사람이 있습니까? 어디서부터 시작해야할까요?


예, 높이와 너비로 iframe 자체를 제한 할 수 없습니다. 주위에 div를 넣어야합니다. iframe의 콘텐츠를 제어하는 ​​경우 터치 이벤트가 수신 될 때 부모에게 div를 스크롤하도록 지시하는 일부 JS를 iframe 콘텐츠 내에 넣을 수 있습니다.

이렇게 :

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를 도입했기 때문에 더 이상 장치에서 자바 스크립트를 디버깅 할 수 없습니다.


iFrame 콘텐츠가 귀하의 것이 아닌 경우 아래 솔루션이 작동하지 않습니다.

Android에서는 iframe을 DIV로 둘러싸고 div의 높이를 document.documentElement.clientHeight로 설정하기 만하면됩니다. 그러나 IOS는 다른 동물입니다. 아직 Sharon의 솔루션을 시도하지 않았지만 좋은 솔루션 인 것 같습니다. 더 간단한 솔루션을 찾았지만 IOS 5. +에서만 작동합니다.

iframe 요소를 DIV (스크롤러라고 부름)로 둘러싸고 DIV의 높이를 설정하고 새 DIV의 스타일이 다음과 같은지 확인합니다.

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

이것만으로도 작동하지만 대부분의 구현에서 스크롤 할 때 iframe의 콘텐츠가 비어 있고 기본적으로 쓸모 없게 렌더링된다는 것을 알 수 있습니다. 내 이해는이 동작이 iOS 5.0부터 Apple에 버그로보고되었다는 것입니다. 이 문제를 해결하려면 iframe에서 body 요소를 찾고 다음과 같이 -webkit-transform ','translate3d (0, 0, 0)를 추가합니다.

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

앱 또는 iframe의 메모리 사용량이 많은 경우 Sharon의 솔루션을 사용해야하는 까다로운 스크롤이 표시 될 수 있습니다.


이것은 외부 페이지와 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를 지정하고 스크롤 가능한 노드로 전환 합니다.


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

나는 내 첫 번째 사이트를 만들고 있는데 이것은 내가 iframe 임베딩을 사용하는 모든 사이트에서 작동하도록 도와주었습니다.

감사!


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

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

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

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.


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

That's it.

ReferenceURL : https://stackoverflow.com/questions/5267996/how-to-properly-display-an-iframe-in-mobile-safari

반응형