문제

나는 igoogle와 같은 응용 프로그램을 연구하고 있습니다. 다른 응용 프로그램 (다른 도메인)의 내용은 iframes를 사용하여 표시됩니다.

iframes 컨텐츠의 높이에 맞게 iframes를 조정하려면 어떻게합니까?

Google이 사용하는 JavaScript를 해독하려고했지만 난독 화되었으며 웹 검색은 지금까지 결실이 없었습니다.

업데이트: 콘텐츠는 다른 도메인에서로드됩니다. 동일한 원래 정책 적용됩니다.

도움이 되었습니까?

해결책

우리는 이러한 유형의 문제가 있었지만 귀하의 상황에 약간 반대입니다. 우리는 다른 도메인의 사이트에 iframed 컨텐츠를 제공하고있었습니다. 동일한 원산지 정책 또한 문제였습니다. Google을 트롤링하는 데 많은 시간을 보낸 후 결국 (다소 ..) 실행 가능한 솔루션을 찾았으며, 이는 귀하의 요구에 적응할 수 있습니다.

동일한 원산지 정책에 대한 방법이 있지만 iframed 컨텐츠와 프레임 페이지 모두에 변경이 필요하므로 양쪽에 변경 사항을 요청할 수없는 경우이 방법은 귀하에게 그다지 유용하지 않습니다. 두렵습니다.

우리가 동일한 원산지 정책을 치울 수있는 브라우저 Quirk가 있습니다. JavaScript는 자체 도메인의 페이지 또는 iframed가있는 페이지와 함께 통신 할 수 있지만 다음과 같은 경우에는 다음과 같은 페이지가 없습니다.

 www.foo.com/home.html, which iframes
 |-> www.bar.net/framed.html, which iframes
     |-> www.foo.com/helper.html

그 다음에 home.html 의사 소통 할 수 있습니다 framed.html (iframed) 및 helper.html (동일한 도메인).

 Communication options for each page:
 +-------------------------+-----------+-------------+-------------+
 |                         | home.html | framed.html | helper.html |
 +-------------------------+-----------+-------------+-------------+
 | www.foo.com/home.html   |    N/A    |     YES     |     YES     |
 | www.bar.net/framed.html |    NO     |     N/A     |     YES     |
 | www.foo.com/helper.html |    YES    |     YES     |     N/A     |
 +-------------------------+-----------+-------------+-------------+

framed.html 메시지를 보낼 수 있습니다 helper.html (iframed)이지만 ~ 아니다 home.html (자녀는 부모와 교차 도메인을 의사 소통 할 수 없습니다).

여기서 핵심은 그 것입니다 helper.html 메시지를받을 수 있습니다 framed.html, 그리고 또한 의사 소통 할 수 있습니다 ~와 함께 home.html.

그래서 본질적으로, 언제 framed.html 하중, 자체 높이에서 작동하며 말합니다. helper.html, 메시지를 전달합니다 home.html, 그런 다음 iframe을 크기를 조정할 수 있습니다 framed.html 앉는다.

우리가 메시지를 전달하는 가장 간단한 방법 framed.html 에게 helper.html URL 인수를 통과했습니다. 이것을하기 위해, framed.html iframe이 있습니다 src='' 지정되었습니다. 그 때 onload 화재, 그것은 자체 높이를 평가 하고이 시점에서 iframe의 SRC를 설정합니다. helper.html?height=N

여기에 설명이 있습니다 Facebook이 어떻게 처리하는지, 위의 내 것보다 약간 명확 할 수 있습니다!


암호

~ 안에 www.foo.com/home.html, 다음 JavaScript 코드가 필요합니다 (이것은 모든 도메인의 .js 파일에서 우연히로드 할 수 있습니다 ..) :

<script>
  // Resize iframe to full height
  function resizeIframe(height)
  {
    // "+60" is a general rule of thumb to allow for differences in
    // IE & and FF height reporting, can be adjusted as required..
    document.getElementById('frame_name_here').height = parseInt(height)+60;
  }
</script>
<iframe id='frame_name_here' src='http://www.bar.net/framed.html'></iframe>

~ 안에 www.bar.net/framed.html:

<body onload="iframeResizePipe()">
<iframe id="helpframe" src='' height='0' width='0' frameborder='0'></iframe>

<script type="text/javascript">
  function iframeResizePipe()
  {
     // What's the page height?
     var height = document.body.scrollHeight;

     // Going to 'pipe' the data to the parent through the helpframe..
     var pipe = document.getElementById('helpframe');

     // Cachebuster a precaution here to stop browser caching interfering
     pipe.src = 'http://www.foo.com/helper.html?height='+height+'&cacheb='+Math.random();

  }
</script>

의 내용 www.foo.com/helper.html:

<html> 
<!-- 
This page is on the same domain as the parent, so can
communicate with it to order the iframe window resizing
to fit the content 
--> 
  <body onload="parentIframeResize()"> 
    <script> 
      // Tell the parent iframe what height the iframe needs to be
      function parentIframeResize()
      {
         var height = getParam('height');
         // This works as our parent's parent is on our domain..
         parent.parent.resizeIframe(height);
      }

      // Helper function, parse param from request string
      function getParam( name )
      {
        name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
        var regexS = "[\\?&]"+name+"=([^&#]*)";
        var regex = new RegExp( regexS );
        var results = regex.exec( window.location.href );
        if( results == null )
          return "";
        else
          return results[1];
      }
    </script> 
  </body> 
</html>

다른 팁

다른 도메인에서 iframe 컨텐츠를 처리 할 필요가 없다면이 코드를 시도하면 문제가 완전히 해결되며 간단합니다.

<script language="JavaScript">
<!--
function autoResize(id){
    var newheight;
    var newwidth;

    if(document.getElementById){
        newheight=document.getElementById(id).contentWindow.document .body.scrollHeight;
        newwidth=document.getElementById(id).contentWindow.document .body.scrollWidth;
    }

    document.getElementById(id).height= (newheight) + "px";
    document.getElementById(id).width= (newwidth) + "px";
}
//-->
</script>

<iframe src="usagelogs/default.aspx" width="100%" height="200px" id="iframe1" marginheight="0" frameborder="0" onLoad="autoResize('iframe1');"></iframe>

https://developer.mozilla.org/en/dom/window.postmessage

Window.postMessage ()

Window.postMessage는 크로스 오리핀 커뮤니케이션을 안전하게 가능하게하는 방법입니다. 일반적으로 다른 페이지의 스크립트는 실행 된 페이지가 동일한 프로토콜 (일반적으로 HTTP), 포트 번호 (80은 HTTP의 기본값) 및 호스트 (모듈로)에있는 경우에만 서로 액세스 할 수 있습니다. Document.Domain은 두 페이지에서 동일한 값으로 설정됩니다). Window.postMessage는 제대로 사용될 때 안전한 방식 으로이 제한을 우회하는 제어 메커니즘을 제공합니다.

요약

Window.postMessage는 호출 될 때 대상 창에 메시지를 발송하여 실행 해야하는 보류중인 스크립트가 완료 될 때 (예 : Window.postMessage가 이벤트 핸들러에서, 이전에 설정중인 시간 초 ). MessageEvent에는 type message, stink.postmessage에 제공된 첫 번째 인수의 문자열 값으로 설정된 데이터 속성이 있습니다. postmessage가 호출되었고 Window.postMessage가 호출되는 창인 소스 속성. (이벤트의 기타 표준 속성은 예상 값이 있습니다.)

그만큼 iframe- 레저 라이저 라이브러리는 사후 관리를 사용하여 Iframe 크기의 콘텐츠와 함께 크기를 유지합니다. 돌연변이 관상 서버 내용의 변경 사항을 감지하고 jQuery에 의존하지 않습니다.

https://github.com/davidjbradshaw/iframe-resizer

jQuery : 크로스 도메인 스크립팅 선함

http://benalman.com/projects/jquery-postmessage-plugin/

Iframe 창에 크기를 조정하는 데모가 있습니다 ...

http://benalman.com/code/projects/jquery-postmessage/examples/iframe/

이 기사는 jQuery에 대한 의존성을 제거하는 방법을 보여줍니다. 또한 많은 유용한 정보와 다른 솔루션에 대한 링크가 있습니다.

http://www.onlineaspect.com/2010/01/15/backwards-compatible-postmessage/

베어 본 예 ...

http://onlineaspect.com/uploads/postmessage/parent.html

HTML 5 Window.postMessage에서 작업 초안

http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossdocumentmessages

John은 Window Messaging을 상환합니다

http://ejohn.org/blog/cross-window-messaging/

jQuery를 사용하는 가장 간단한 방법 :

$("iframe")
.attr({"scrolling": "no", "src":"http://www.someotherlink.com/"})
.load(function() {
    $(this).css("height", $(this).contents().height() + "px");
});

해결책 http://www.phinesolutions.com/use-jquery-to-adjust-the-iframe-height.html 잘 작동합니다 (jQuery 사용) :

<script type=”text/javascript”>
  $(document).ready(function() {
    var theFrame = $(”#iFrameToAdjust”, parent.document.body);
    theFrame.height($(document.body).height() + 30);
  });
</script>

나는 당신이 길이에 30을 추가해야한다는 것을 모른다 ... 1은 나를 위해 일했다.

참고로: iframe에 이미 "높이"속성이 있다면 스타일 = "높이 : xxx"를 추가합니다. 이것은 당신이 원하는 것이 아닐 수도 있습니다.

다른 모든 대답은 나이가 들기 때문에 조금 늦을 수 있습니다 :-) 그러나 ... 여기 내 해결책입니다. 실제 FF, Chrome 및 Safari 5.0에서 테스트.

CSS :

iframe {border:0; overflow:hidden;}

자바 스크립트 :

$(document).ready(function(){
    $("iframe").load( function () {
        var c = (this.contentWindow || this.contentDocument);
        if (c.document) d = c.document;
        var ih = $(d).outerHeight();
        var iw = $(d).outerWidth();
        $(this).css({
            height: ih,
            width: iw
        });
    });
});

이것이 누구나 도움이되기를 바랍니다.

마지막으로 iframe에서 부모 웹 사이트로 데이터를 전송하기위한 다른 솔루션을 찾았습니다. window.postMessage(message, targetOrigin);. 여기서 나는 내가 어떻게했는지 설명합니다.

사이트 a = http://foo.com 사이트 b = http://bar.com

SiteB는 Siteea 웹 사이트 내부에로드 중입니다

SiteB 웹 사이트에는이 라인이 있습니다

window.parent.postMessage("Hello From IFrame", "*"); 

또는

window.parent.postMessage("Hello From IFrame", "http://foo.com");

그런 다음 Sitea는 다음 코드를 가지고 있습니다

// Here "addEventListener" is for standards-compliant web browsers and "attachEvent" is for IE Browsers.
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
var eventer = window[eventMethod];


var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";

// Listen to message from child IFrame window
eventer(messageEvent, function (e) {
   alert(e.data);
   // Do whatever you want to do with the data got from IFrame in Parent form.
}, false); 

보안 연결을 추가하려면 IF 조건을 사용할 수 있습니다. eventer(messageEvent, function (e) {})

if (e.origin == 'http://iframe.example.com') {
    alert(e.data); 
    // Do whatever you want to do with the data got from IFrame in Parent form.
}

IE를 위해

내부 Iframe :

 window.parent.postMessage('{"key":"value"}','*');

밖의:

 eventer(messageEvent, function (e) {
   var data = jQuery.parseJSON(e.data);
   doSomething(data.key);
 }, false);

다음은 iframe 컨텐츠와 동일한 서버에서 제공하는 동적으로 생성 된 스타일 시트를 사용하는 간단한 솔루션입니다. 단순히 스타일 시트는 iframe의 내용을 "알고 있으며 Iframe 스타일을 유지하는 데 사용할 차원을 알고 있습니다. 이것은 동일한 원산지 정책 제한을 가져옵니다.

http://www.8degrees.co.nz/2010/06/09/dynamically-Resize-an-iframe-depending-on-ist-content/

따라서 제공된 iframe 코드에는 동반 스타일 시트가 있습니다.

<link href="http://your.site/path/to/css?contents_id=1234&dom_id=iframe_widget" rel="stylesheet" type="text/css" />
 <iframe id="iframe_widget" src="http://your.site/path/to/content?content_id=1234" frameborder="0" width="100%" scrolling="no"></iframe>

이를 위해서는 서버 측 논리가 Iframe의 렌더링 된 내용의 크기를 계산할 수 있어야합니다.

이 답변은 부트 스트랩을 사용하는 웹 사이트에만 적용됩니다. 부트 스트랩의 반응 형 포함 기능이 작업을 수행합니다. 내용의 너비 (높이가 아님)를 기준으로합니다.

<!-- 16:9 aspect ratio -->
<div class="embed-responsive embed-responsive-16by9">
  <iframe class="embed-responsive-item" src="http://www.youtube.com/embed/WsFWhL4Y84Y"></iframe>
</div>

jsfiddle : http://jsfiddle.net/00qggsjj/2/

http://getbootstrap.com/components/#responsive-embed

문서 설정을 기반으로 솔루션을 대체하기 위해 Conroyp의 프레임-프레임 솔루션을 구현하고 있지만 다른 브라우저 (FF11, CH17 및 IE9로 테스트하는 IFRAME 컨텐츠의 높이를 올바르게 결정하는 것은 매우 어렵다는 것을 발견했습니다. ).

Conroyp 사용 :

var height = document.body.scrollHeight;

그러나 그것은 초기 페이지로드에서만 작동합니다. Iframe에는 동적 콘텐츠가 있으며 특정 이벤트에서 iframe을 크기를 조정해야합니다.

내가 한 일은 다른 브라우저에 다른 JS 속성을 사용하는 것이 었습니다.

function getDim () {
    var body = document.body,
        html = document.documentElement;

    var bc = body.clientHeight;
    var bo = body.offsetHeight;
    var bs = body.scrollHeight;
    var hc = html.clientHeight;
    var ho = html.offsetHeight;
    var hs = html.scrollHeight;

    var h = Math.max(bc, bo, bs, hc, hs, ho);

    var bd = getBrowserData();

    // Select height property to use depending on browser
    if (bd.isGecko) {
        // FF 11
        h = hc;
    } else if (bd.isChrome) {
        // CH 17
        h = hc;
    } else if (bd.isIE) {
        // IE 9
        h = bs;
    }

    return h;
}

getBrowserData ()는 브라우저가 Ext Core 's에서 "Inspired"기능을 감지합니다. http://docs.sencha.com/core/source/ext.html#method-ext-apply

그것은 FF와 IE에게 잘 작동했지만 Chrome에는 문제가있었습니다. 타이밍 문제 중 하나는 Iframe의 Hight를 설정/감지하는 데 Chrome이 시간이 걸립니다. 그리고 iframe이 컨텐츠보다 높은 경우 Chrome은 Iframe의 컨텐츠 높이를 올바르게 반환하지 않았습니다. 높이가 줄어드는 경우 동적 콘텐츠에서는 작동하지 않습니다.

이를 해결하기 위해 컨텐츠의 높이를 감지 한 다음 Iframe 높이를 올바른 값으로 설정하기 전에 항상 Iframe을 낮은 높이로 설정했습니다.

function resize () {
    // Reset the iframes height to a low value.
    // Otherwise Chrome won't detect the content height of the iframe.
    setIframeHeight(150);

    // Delay getting the dimensions because Chrome needs
    // a few moments to get the correct height.
    setTimeout("getDimAndResize()", 100);
}

코드는 최적화되지 않았으며, 디벨 테스트에서 나온 것입니다 :)

누군가가 도움이되기를 바랍니다!

<html>
<head>
<script>
function frameSize(id){
var frameHeight;

document.getElementById(id).height=0 + "px";
if(document.getElementById){
    newheight=document.getElementById(id).contentWindow.document.body.scrollHeight;    
}

document.getElementById(id).height= (frameHeight) + "px";
}
</script>
</head>

<body>

<iframe id="frame"  src="startframe.html" frameborder="0" marginheight="0" hspace=20     width="100%" 

onload="javascript:frameSize('frame');">

<p>This will work, but you need to host it on an http server, you can do it locally.    </p>
</body>
</html>

igoogle 가제트는 크기 조정을 적극적으로 구현해야하므로, 내 추측은 어떤 식 으로든 원격 컨텐츠를 사용하지 않으면 할 수없는 크로스 도메인 모델입니다. 콘텐츠가 일반적인 크로스 도메인 커뮤니케이션 기술을 사용하여 컨테이너 페이지에 새 크기의 메시지를 보낼 수 있다면 나머지는 간단합니다.

웹 페이지를 확대하여 iframe 크기에 맞추기 위해 :

  1. 당신은 크기를 조정해야합니다 Iframe 콘텐츠에 맞추기 위해
  2. 그런 다음로드 된 웹 페이지 컨텐츠로 전체 iframe을 축소해야합니다.

예는 다음과 같습니다.

<div id="wrap">
   <IFRAME ID="frame" name="Main" src ="http://www.google.com" />
</div>

<style type="text/css">
    #wrap { width: 130px; height: 130px; padding: 0; overflow: hidden; }
    #frame { width: 900px; height: 600px; border: 1px solid black; }
    #frame { zoom:0.15; -moz-transform:scale(0.15);-moz-transform-origin: 0 0; }
</style>

다음은 iframe의 SRC 속성을 통해 JSON의 정보를 추가하는 jQuery 접근법입니다. 여기에 데모, 크기 조정 및 스크롤이 있습니다.http://fiddle.jshell.net/zippyskippy/rjn3g/show/# {docheight:5124

소스 코드 바이올린은 다음과 같습니다 http://jsfiddle.net/zippyskippy/rjn3g/

function updateLocation(){

    var loc = window.location.href;
    window.location.href = loc.replace(/#{.*}#/,"") 
        + "#{docHeight:"+$(document).height() 
        + ",windowHeight:"+$(window).height()
        + ",scrollHeight:"+$(window).scrollTop()
        +"}#";

};

//setInterval(updateLocation,500);

$(window).resize(updateLocation);
$(window).scroll(updateLocation);

iframe 컨텐츠 높이를 얻은 다음이 iframe에게 제공하십시오.

 var iframes = document.getElementsByTagName("iframe");
 for(var i = 0, len = iframes.length; i<len; i++){
      window.frames[i].onload = function(_i){
           return function(){
                     iframes[_i].style.height = window.frames[_i].document.body.scrollHeight + "px";
                     }
      }(i);
 }

jQuery on Load (크로스 브라우저)와 함께 작업 :

 <iframe src="your_url" marginwidth="0"  marginheight="0" scrolling="No" frameborder="0"  hspace="0" vspace="0" id="containiframe" onload="loaderIframe();" height="100%"  width="100%"></iframe>

function loaderIframe(){
var heightIframe = $('#containiframe').contents().find('body').height();
$('#frame').css("height", heightFrame);
 }  

반응 형 페이지에서 크기 조정 :

$(window).resize(function(){
if($('#containiframe').length !== 0) {
var heightIframe = $('#containiframe').contents().find('body').height();
 $('#frame').css("height", heightFrame);
}
});

jQuery 사용 :

parent.html

<body>
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<style>
iframe {
    width: 100%;
    border: 1px solid black;
}
</style>
<script>
function foo(w, h) {
    $("iframe").css({width: w, height: h});
    return true;  // for debug purposes
}
</script>
<iframe src="child.html"></iframe>
</body>

child.html

<body>
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script>
$(function() {
    var w = $("#container").css("width");
    var h = $("#container").css("height");

    var req = parent.foo(w, h);
    console.log(req); // for debug purposes
});
</script>
<style>
body, html {
    margin: 0;
}
#container {
    width: 500px;
    height: 500px;
    background-color: red;
}
</style>
<div id="container"></div>
</body>

Iframe 페이지가로드되었을 때 알아야 할 때 약간 까다로워요. 콘텐츠를 제어하지 않을 때는 어려운 일입니다. IFRAME에 OnLoad 핸들러를 추가 할 수는 있지만 과거에는 이것을 시도했는데 브라우저에서 동작이 크게 다릅니다 (누가 가장 성가신 사람인지 추측하지 않습니다 ...). Iframe 페이지에 함수를 추가하여 크기 조정을 수행하고 이벤트로드하거나 이벤트 크기를 청소하는 컨텐츠에 일부 스크립트를 주입 한 다음 이전 기능을 호출해야 할 것입니다. 안전을 확인하고 싶기 때문에 페이지에 함수를 추가하고 있다고 생각하지만 얼마나 쉬운 지 모르겠습니다.

내가 믿고있는이 선의 어떤 것이 효과가 있어야합니다.

parent.document.getElementById(iFrameID).style.height=framedPage.scrollHeight;

Iframe 콘텐츠에 신체 온로드로 이것을로드하십시오.

쉬운 솔루션이 있으며 링크의 너비와 높이를 결정해야합니다. 시도하십시오 (대부분의 브라우저에서 작동).

<a href='#' onClick=" document.getElementById('myform').src='t2.htm';document.getElementById('myform').width='500px'; document.getElementById('myform').height='400px'; return false">500x400</a>
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top