การปรับขนาด iframe ข้ามโดเมน


85

ฉันจะปรับขนาด iframe จากโดเมนอื่นได้อย่างไร

- แก้ไข

เลื่อนลงเพื่อดูวิธีแก้ปัญหา .. หรืออ่านวิธีการไม่ทำสิ่งนี้

หลังจากแฮ็กโค้ดหลายชั่วโมงข้อสรุปก็คือไม่สามารถเข้าถึงสิ่งใด ๆ ภายใน iframe ได้แม้แต่แถบเลื่อนที่แสดงผลบนโดเมนของฉัน ฉันได้ลองใช้เทคนิคมากมายแล้วก็ไม่เกิดประโยชน์

เพื่อช่วยคุณประหยัดเวลาอย่าแม้แต่ไปตามเส้นทางนี้เพียงแค่ใช้ sendMessages สำหรับการสื่อสารข้ามโดเมน มีปลั๊กอินสำหรับ HTML <5 ที่ฉันใช้ - ไปที่ด้านล่างเพื่อดูตัวอย่างที่ดี :)


ไม่กี่วันที่ผ่านมาฉันพยายามรวม iframe เข้ากับไซต์ นี่เป็นวิธีแก้ปัญหาระยะสั้นในขณะที่อีกด้านหนึ่งพัฒนาและ API (อาจใช้เวลาหลายเดือน ... ) และเนื่องจากนี่เป็นวิธีการแก้ปัญหาระยะสั้นที่เราต้องการใช้ easyXDM - ฉันสามารถเข้าถึงโดเมนอื่นได้ แต่ก็ยากพอที่จะขอให้พวกเขา เพิ่ม p3p header ตามที่เป็น .....

3 iframe

ทางออกที่ใกล้เคียงที่สุดที่ฉันพบคือ 3 iframes - แต่มันเป็นไปในแง่ของ Chrome และ Safari ดังนั้นฉันจึงไม่สามารถใช้สิ่งนั้น

เปิดใน chrome

http://css-tricks.com/examples/iFrameResize/crossdomain.php#frameId=frame-one&height=1179

วัดแถบเลื่อน

ฉันพบโพสต์อื่นเกี่ยวกับวิธีใช้ scrollheight เพื่อลองและปรับขนาดฟอร์ม .. ในทางทฤษฎีมันใช้ได้ดี แต่ฉันไม่สามารถใช้มันอย่างถูกต้องโดยใช้ความสูงของการเลื่อน iframe

document.body.scrollHeight

สิ่งนั้นใช้ความสูงของร่างกายอย่างไม่เหมาะสม (ไม่สามารถเข้าถึงคุณสมบัติเหล่านี้ได้ 100% ขึ้นอยู่กับ canvaz ที่ไคลเอ็นต์แสดงและไม่ใช่ความสูงของเอกสาร x-domains)

ฉันลองใช้ jquery เพื่อรับความสูงของ iframe

$('#frameId').Height()

$('#frameId').clientHeight

$('#frameId').scrollHeight

ส่งคืนค่าที่แตกต่างกันใน chrome และ ie - หรือไม่สมเหตุสมผลเลย ปัญหาคือทุกอย่างในเฟรมถูกปฏิเสธแม้กระทั่งแถบเลื่อน ...

รูปแบบการคำนวณ

แต่ถ้าฉันตรวจสอบและองค์ประกอบในโครเมี่ยมของ iframe มัน bladdy แสดงขนาดเอกสารภายใน iframe (โดยใช้ jquery x-domain เพื่อรับ iframe.heigh - การเข้าถึงถูกปฏิเสธ) ไม่มีอะไรใน CSS ที่คำนวณ ใส่คำอธิบายภาพที่นี่

ตอนนี้ Chrome คำนวณได้อย่างไร? (แก้ไข - เบราว์เซอร์แสดงผลหน้าเว็บอีกครั้งโดยใช้บิลด์ในเอ็นจิ้นการเรนเดอร์เพื่อคำนวณการตั้งค่าเหล่านี้ทั้งหมด - แต่ไม่ได้เชื่อมต่อที่ใดก็ได้เพื่อป้องกันการฉ้อโกงข้ามโดเมน .. ดังนั้น .. )

HTML4

ฉันอ่านข้อกำหนดของ HTML4.x และมันบอกว่าควรมีค่าอ่านอย่างเดียวที่เปิดเผยผ่าน document.element แต่การเข้าถึงถูกปฏิเสธผ่าน jquery

กรอบพร็อกซี

ฉันเดินไปตามเส้นทางของการพร็อกซีไซต์กลับและคำนวณว่าตกลง .. จนกว่าผู้ใช้จะเข้าสู่ระบบผ่าน iframe และพร็อกซีจะได้รับหน้าเข้าสู่ระบบแทนเนื้อหาจริง นอกจากนี้สำหรับบางคนที่เรียกหน้าสองครั้งก็ไม่เป็นที่ยอมรับ

http://www.codeproject.com/KB/aspnet/asproxy.aspx

http://www.johnchapman.name/aspnet-proxy-page-cross-domain-requests-from-ajax-and-javascript/

Re-Render หน้า

ฉันไม่ได้ไปไกลขนาดนี้ แต่มีเอ็นจิ้น jscript อยู่ที่นั่นซึ่งจะดูแหล่งที่มาและแสดงผลหน้าเว็บอีกครั้งตามไฟล์ต้นฉบับ แต่มันจะต้องมีการแฮ็ก jscripts เหล่านั้น .. และนั่นไม่ใช่สถานการณ์ที่เหมาะสำหรับเอนทิตีเชิงพาณิชย์ ...

http://en.wikipedia.org/wiki/Server-side_JavaScript

http://htmlunit.sourceforge.net/ <-java ไม่ใช่ jscript

http://maxq.tigris.org/


แก้ไข 09-2013 อัพเดท

ทั้งหมดนี้สามารถทำได้ด้วยซ็อกเก็ต HTML5 แต่ easyXDM เป็นทางเลือกที่ดีสำหรับหน้าร้องเรียนที่ไม่ใช่ HTML5

โซลูชันที่ 1 ทางออกที่ยอดเยี่ยมมาก!

ใช้ easyXDM

บนเซิร์ฟเวอร์ของคุณคุณตั้งค่าเพจในรูปแบบ

<html>
<head>
<script src="scripts/easyXDM.js" type="text/javascript"></script>
<script type="text/javascript" language="javascript">

    var transport = new easyXDM.Socket(/** The configuration */{
    remote: "http://www.OTHERDOMAIN.com/resize_intermediate.html?url=testpages/resized_iframe_1.html",

    //ID of the element to attach the inline frame to
    container: "embedded",
    onMessage: function (message, origin) {
        var settings = message.split(",");
        //Use jquery on a masterpage.
        //$('iframe').height(settings[0]);
        //$('iframe').width(settings[1]);

        //The normal solution without jquery if not using any complex pages (default)
        this.container.getElementsByTagName("iframe")[0].style.height = settings[0];
        this.container.getElementsByTagName("iframe")[0].style.width = settings[1];
    }
});

</script>

</head>

<body>
    <div id="embedded"></div>
</body>

และบนโดเมนผู้โทรพวกเขาเพียงแค่ต้องเพิ่ม intermiedate_frame html และ easyXDM.js ในที่เดียวกัน เช่นเดียวกับโฟลเดอร์หลักคุณสามารถเข้าถึงไดเร็กทอรีสัมพัทธ์หรือโฟลเดอร์ที่มีอยู่สำหรับคุณโดยเฉพาะ

ตัวเลือกที่ 1

หากคุณไม่ต้องการเพิ่มสคริปต์ในทุกหน้าให้ดูที่ตัวเลือกที่ 2!

จากนั้นพวกเขาสามารถเพิ่ม jscript แบบธรรมดาที่ส่วนท้ายของแต่ละหน้าที่คุณต้องการให้การปรับขนาดเกิดขึ้น ไม่จำเป็นต้องรวม easyxdm ไว้ในแต่ละหน้า

 <script type="text/javascript">
            window.onload = function(){ parent.socket.postMessage( (parseInt(document.body.clientHeight)) + "," + ( document.body.clientWidth ) );  };
        </script>

ฉันได้แก้ไขพารามิเตอร์ที่ส่งไป หากคุณต้องการให้ความกว้างทำงานได้อย่างถูกต้องหน้าในโดเมนอื่นจะต้องมีความกว้างของหน้าในลักษณะที่มีลักษณะคล้ายกับ:

<style type="text/css">
            html, body {
                overflow: hidden;
                margin: 0px;
                padding: 0px;
                background-color: rgb(75,0,85);
                color:white;
                width:660px
            }
            a {
            color:white;
            visited:white;
            }
        </style>

สิ่งนี้ใช้ได้ดีสำหรับฉัน หากไม่รวมความกว้างเฟรมจะทำงานแปลก ๆ เล็กน้อยและพยายามเดาว่ามันควรจะเป็นอะไร .. และจะไม่ย่อขนาดลงหากคุณต้องการ

ตัวเลือก 2

แก้ไขกรอบกลางเพื่อสำรวจความเปลี่ยนแปลง

กรอบกลางของคุณควรมีลักษณะดังนี้ ..

    <!doctype html>
<html>
    <head>

        <title>Frame</title>
        <script type="text/javascript" src="easyXDM.js">
        </script>
        <script type="text/javascript">
            var iframe;
            var socket = new easyXDM.Socket({
                //This is a fallback- not needed in many cases
                swf: "easyxdm.swf",
                onReady: function(){
                    iframe = document.createElement("iframe");
                    iframe.frameBorder = 0;
                    document.body.appendChild(iframe);
                    iframe.src = "THE HOST FRAME";
            iframe.onchange = messageBack();

                },
                onMessage: function(url, origin){
                    iframe.src = url;
                }
            });

            //Probe child.frame for dimensions.
            function messageBack(){
                socket.postMessage ( iframe.contentDocument.body.clientHeight + "," + iframe.contentDocument.body.clientWidth); 
            };

            //Poll for changes on children every 500ms.
            setInterval("messageBack()",500); 

        </script>
        <style type="text/css">
            html, body {
                overflow: hidden;
                margin: 0px;
                padding: 0px;
                width: 100%;
                height: 100%;
            }

            iframe {
                width: 100%;
                height: 100%;
                border: 0px;
            }
        </style>
    </head>
    <body>

    </body>
</html>

ช่วงเวลาสามารถทำให้มีประสิทธิภาพมากขึ้นในการกำหนดขนาดหากขนาดมีการเปลี่ยนแปลงและส่งเฉพาะในกรณีที่มิติเปลี่ยนแปลงไม่ใช่การโพสต์ข้อความทุกๆ 500 มิลลิวินาที หากคุณใช้การตรวจสอบนี้คุณสามารถเปลี่ยนการสำรวจต่ำสุด 50 มิลลิวินาทีได้! มีความสุข


ทำงานบนเบราว์เซอร์และรวดเร็ว คุณสมบัติการแก้จุดบกพร่องที่ยอดเยี่ยม !!

Excellent Work to  Sean Kinsey  who made the script!!!

โซลูชันที่ 2 (ใช้งานได้ แต่ไม่ดี)

ดังนั้นโดยพื้นฐานแล้วหากคุณมีข้อตกลงร่วมกันกับโดเมนอื่นคุณสามารถเพิ่มไลบรารีเพื่อจัดการการส่งข้อความได้ หากคุณไม่สามารถเข้าถึงโดเมนอื่นได้ .. มองหาแฮ็กเพิ่มเติมต่อไปเพราะฉันไม่สามารถหาหรือแก้ไขสิ่งเหล่านี้ได้ทั้งหมด

ดังนั้นโดเมนอื่นจะรวมสิ่งเหล่านี้ไว้ในแท็ก Head ด้วย

<script src="scripts/jquery-1.5.2.min.js" type="text/javascript"></script>
<script src="scripts/jquery.postmessage.min.js" type="text/javascript"></script>
<script src="scripts/club.js" type="text/javascript"></script>

ใน club.js เป็นเพียงการโทรที่กำหนดเองบางส่วนที่ฉันสร้างขึ้นเพื่อปรับขนาดการโทรและมี ..

 $(document).ready(function () {   
    var parent_url = decodeURIComponent( document.location.hash.replace( /^#/, '' ) ),link;
//Add source url hash to each url to authorise callback when navigating inside the frame.Without this clicking any links will break the communication and no messages will be received
$('a[href]').each(function(){ 
     this.href = this.href + document.location.hash ;
});
//Get the dimensions and send back to calling page.
var h1 = document.body.scrollHeight;
var w1 = document.body.scrollWidth;
$.postMessage({ if_height: h1, if_width: w1 }, parent_url, parent );
  });

และเพจของคุณจะทำงานอย่างเต็มที่และมีสคริปต์ที่ดี ...

  //This is almost like request.querystring used to get the iframe data
  function querySt(param, e) {
         gy = e.split("&");
         for (i = 0; i < gy.length; i++) {
             ft = gy[i].split("=");
             if (ft[0] == param) {
                 return ft[1];
             }
         }
     }


     $(function () {
         // Keep track of the iframe dimensions.
         var if_height;
         var if_width;
         // Pass the parent page URL into the Iframe in a meaningful way (this URL could be
         // passed via query string or hard coded into the child page, it depends on your needs).
         src = 'http://www.OTHERDOAMIN.co.uk/OTHERSTARTPAGE.htm' + '#' + encodeURIComponent(document.location.href),
         // Append the Iframe into the DOM.
         iframe = $('<iframe " src="' + src + '" width="100%" height="100%" scrolling="no" frameborder="0"><\/iframe>').appendTo('#iframe');

         // Setup a callback to handle the dispatched MessageEvent event. In cases where
         // window.postMessage is supported, the passed event will have .data, .origin and
         // .source properties. Otherwise, this will only have the .data property.
         $.receiveMessage(function (e) {
             // Get the height from the passsed data.
             //var h = Number(e.data.replace(/.*if_height=(\d+)(?:&|$)/, '$1'));
             var h = querySt("if_height", e.data);
             var w = querySt("if_width", e.data);


             if (!isNaN(h) && h > 0 && h !== if_height) {
                 // Height has changed, update the iframe.
                 iframe.height(if_height = h);
             }
             if (!isNaN(w) && w > 0 && w !== if_width) {
                 // Height has changed, update the iframe.
                 iframe.width(if_width = w);
             }
             //For debugging only really- can remove the next line if you want
             $('body').prepend("Recieved" + h + "hX" + w + "w .. ");
             // An optional origin URL (Ignored where window.postMessage is unsupported).
           //Here you must put the other domain.com name only! This is like an authentication to prevent spoofing and xss attacks! 
         }, 'http://www.OTHERDOMAIN.co.uk');
     });

ตัวเลือก 3

ตอนนี้เป็นไลบรารี JS ขนาดเล็กสำหรับจัดการการปรับขนาด iFrames ข้ามโดเมน แต่ยังต้องใช้ iFrame เพื่อให้มี JavaScript อยู่เล็กน้อยอย่างไรก็ตามนี่เป็นเพียง 2.8k (765 bytes Gzipped) ของ JS ดั้งเดิมที่ไม่มีการพึ่งพาใด ๆ และจะไม่ทำอะไรจนกว่าเพจหลักจะเรียก ซึ่งหมายความว่าเป็นแขกที่ดีในระบบของคนอื่น

รหัสนี้ใช้ mutationObserver เพื่อตรวจจับการเปลี่ยนแปลงของ DOM และยังมองหาการปรับขนาดเหตุการณ์เพื่อให้ iFrame ยังคงปรับขนาดให้เข้ากับเนื้อหา ทำงานใน IE8 +

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


4
ตัวอย่าง easyXDM มีโค้ดน้อยกว่ามากไม่ต้องพึ่งพา libs ภายนอกและยังใช้งานได้กับเบราว์เซอร์รุ่นเก่า :) และใช่ฉันลำเอียงตั้งแต่ฉันเป็นผู้เขียน แต่ก็ยัง ..
Sean Kinsey

ฉันลอง easyXDM แต่ไม่สามารถเรียกดูเฟรมภายในไปยังลิงก์อื่นเพื่อทำงานได้ .. ฉันมองหาตัวอย่าง .. มีลิงค์ที่พังและหน้าตัวอย่างไม่ชัดเจน .. มันใช้งานได้! และเป็นคำตอบเดิมของฉัน .. แต่ฉันใช้สิ่งนี้ คุณช่วยโพสต์วิธีการเรียกดูภายในได้ไหม .. ฉันดูแล้ว ..
Piotr Kula

@ppumkin ตัวอย่างที่มาพร้อมกับการดาวน์โหลดรองรับการเรียกดูภายในอย่างสมบูรณ์ ลิงก์เสียน่าจะเป็นการทดลองที่ฉันทำ แต่เซิร์ฟเวอร์ถูกล้างเมื่อถึงจุดหนึ่ง ..
Sean Kinsey

1
ใช่มองไปที่นั่น - และมองและมอง: D ด้วยเหตุผลบางอย่างฉันไม่สามารถทำให้มันทำงานกับไซต์ของฉัน ฉันจะลองอีกครั้ง
Piotr Kula

1
มันใช้งานได้ - แต่ถ้าฉันคลิกลิงก์บนโดเมนนั้นมันจะโหลดเพจซ้ำ - กับไลบรารีของคุณ - แต่ฉันไม่สามารถรับข้อความใด ๆ ฉันจะยอมรับคำขอได้อย่างไรไม่ว่าจะมาจากที่ใด แล้ว easyxdm.swf นี้มีไว้ทำอะไร? :)
Piotr Kula

คำตอบ:


10

สิ่งนี้คือ - ไม่มีวิธีอื่นใดนอกจากการใช้การส่งข้อความข้ามโดเมนสำหรับสิ่งนี้เนื่องจากคุณต้องได้รับความสูงที่คำนวณจากเอกสารในโดเมนเดียวไปยังเอกสารในโดเมนอื่น

ดังนั้นคุณจะทำสิ่งนี้โดยใช้postMessage(ใช้ได้กับเบราว์เซอร์ตัวดัดแปลงทั้งหมด) หรือคุณใช้เวลา 5 นาทีในการปรับตัวอย่าง iframe ปรับขนาดจาก easyXDM

อีกฝ่ายต้องการแค่คัดลอกไฟล์สองสามไฟล์ไปยังโดเมนของตนและเพิ่มโค้ดบรรทัดเดียวในเอกสารของตน ..


ในทางตรงกันข้ามเพื่อนของฉัน ฉันพบวิธีปรับขนาด iframe จากหน้า cross doimain เป็นขนาด docuemnt ของ iframes และไม่มีแถบเลื่อน มันค่อนข้างแฮ็ค แต่จะโพสต์ในภายหลัง .. มันง่ายมากจนไม่น่าเชื่อ
Piotr Kula

ใช่ ... ฉันใช้ปลั๊กอิน sendmessage jquwery - ฉันพบแฮ็คอื่น - บวกเท็จ .. ;) ขอบคุณสำหรับเคล็ดลับที่ดี!
Piotr Kula

บางครั้งสิ่งที่ดีที่สุดคือการฟังเพื่อนของคุณ - โอกาสที่คุณจะค้นพบการแฮ็กมายากลที่ไม่มีใครมีก็ค่อนข้างผอม :)
Sean Kinsey

ลองนึกดูว่าถ้าฉันทำโดยการตีและพลาดอย่างแท้จริง - จะยอดเยี่ยมมาก แต่ใช่แล้ว: D ขอบคุณ
Piotr Kula

จริง - ถ้าไม่มีอะไรอย่างอื่นคุณได้ลองทดลองและอาจจะได้เรียนรู้สิ่งใหม่ ๆ เช่นกัน :)
Sean Kinsey

26

เช่นเดียวกับสิ่งที่ฌอนกล่าวถึงคุณสามารถใช้ postMessage ฉันใช้เวลามากมายในการลองวิธีต่างๆในการปรับขนาด iframe ด้วยการข้ามโดเมน แต่โชคไม่ดีจนกระทั่งฉันไปสะดุดกับบล็อกโพสต์ที่ยอดเยี่ยมนี้โดย David Walsh: http://davidwalsh.name/window-iframe

นี่คือการรวมกันระหว่างรหัสของฉันและโซลูชันของเดวิด โซลูชันของฉันมุ่งเน้นไปที่การปรับขนาด iframe โดยเฉพาะ

ในเพจย่อยค้นหาความสูงของเพจและส่งต่อไปยังเพจพาเรนต์ (ซึ่งมี iframe) แทนที่ element_id ด้วยรหัสองค์ประกอบของคุณ (html, body, อะไรก็ได้)

<script>
function adjust_iframe_height(){
    var actual_height = document.getElementById('element_id).scrollHeight;
    parent.postMessage(actual_height,"*"); 
    //* allows this to post to any parent iframe regardless of domain
}
</script>

<body onload="adjust_iframe_height();"> 
//call the function above after the content of the child loads

ในหน้าต่างหลักให้เพิ่มรหัสนี้ แทนที่ iframe_id ด้วย iframe ID ของคุณ:

<script>
// Create IE + others compatible event handler
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
var eventer = window[eventMethod];
var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";

// Listen to message from child window
eventer(messageEvent,function(e) {
  console.log('parent received message!:  ',e.data);
  document.getElementById('iframe_id').height = e.data + 'px';
},false);
</script>

หากคุณเปิดคอนโซลคุณจะเห็นความสูงถูกพิมพ์ในบันทึกของคอนโซล สิ่งนี้จะช่วยคุณในการแก้ไขข้อบกพร่องซึ่งเป็นสาเหตุที่ฉันทิ้งไว้ที่นั่น

ดีที่สุด Baker


ใช้งานได้ดี แต่ไม่มากเท่าใน IE ฉันต้องส่งตัวแปร 2 ตัว แต่ IE จะไม่ยอมรับ "ข้อมูล" หากเป็นอาร์เรย์หรือวัตถุ อย่างไรก็ตามฉันเพิ่งสร้างข้อมูลเป็น data = var1 + "|" var2. บนพาเรนต์คุณเพิ่งแยกสตริงบน | และรับ 2 ตัวแทนของคุณคืน
dbonneville

5

หลังจากดูวิธีแก้ปัญหาที่แตกต่างกันมากมายแล้วฉันจึงเขียนไลบรารีขนาดเล็กธรรมดา ๆ เพื่อพิจารณากรณีการใช้งานที่แตกต่างกันจำนวนมาก เนื่องจากฉันต้องการโซลูชันที่รองรับ iFrames ที่สร้างโดยผู้ใช้หลายคนบนเพจพอร์ทัลเบราว์เซอร์ที่รองรับจะปรับขนาดและสามารถรับมือกับการโหลด JavaScript ของโฮสต์เพจหลังจาก iFrame ฉันยังเพิ่มการสนับสนุนสำหรับการปรับขนาดให้เป็นความกว้างและฟังก์ชันการเรียกกลับและอนุญาตให้มีการแทนที่ body.margin เนื่องจากคุณอาจต้องการให้ชุดนี้เป็นศูนย์

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

โค้ด iframe เป็นเพียง JavaScript ที่มีอยู่ในตัวเล็กน้อยเพื่อให้เป็นแขกที่ดีในหน้าคนอื่น ๆ

จากนั้นสคริปต์จะเริ่มต้นบนหน้าโฮสต์ด้วยตัวเลือกที่มีดังต่อไปนี้

iFrameResize({
    log                    : true,  // For development
    autoResize             : true,  // Trigering resize on events in iFrame
    contentWindowBodyMargin: 8,     // Set the default browser body margin style (in px)
    doHeight               : true,  // Calculates dynamic height
    doWidth                : false, // Calculates dynamic width
    enablePublicMethods    : true,  // Enable methods within iframe hosted page 
    interval               : 32,    // interval in ms to recalculate body height, 0 to disable refreshing
    scrolling              : false, // Enable the scrollbars in the iFrame
    callback               : function(messageData){ // Callback fn when message is received
        $('p#callback').html(
            '<b>Frame ID:</b> '    + messageData.iframe.id +
            ' <b>Height:</b> '     + messageData.height +
            ' <b>Width:</b> '      + messageData.width + 
            ' <b>Event type:</b> ' + messageData.type
        );
    }
});

เพื่อนดีคนหนึ่ง แน่นอนบางสิ่งบางอย่างที่จะถูกใช้โดยผู้คน! +1
Piotr Kula

1
ฉันจะทำอย่างไรหากไม่สามารถเข้าถึงโดเมนระยะไกลได้ ขอบคุณ
Bala Peterson

@BalaPeterson หากคุณไม่สามารถเข้าถึงโดเมนระยะไกลคุณจะไม่สามารถทำได้เนื่องจากข้อ จำกัด ด้านความปลอดภัยในเบราว์เซอร์
David Bradshaw

0

แทนที่จะใช้ scroll = no บน iframe ฉันเปลี่ยนเป็น "auto" จากนั้นฉันจะได้ขนาดของหน้าต่างจริง

$(window).height();

และใช้เป็นแอตทริบิวต์ iframe height

ผลลัพธ์คือ ...

เราจะไม่มีการเลื่อน "เพจ" มีเพียงการเลื่อน "iframe" เมื่อคุณนำทางไม่ว่าใครจะเป็นผู้เลื่อน แต่สิ่งสำคัญคือมีเพียง 1 เท่านั้น

มีปัญหาของผู้ใช้เพียงแค่ปรับขนาดหน้าต่างในขณะที่เขานำทาง เพื่อแก้ปัญหานั้นฉันใช้:

setInterval(getDocHeight, 1);

คุณคิดว่าการแก้ปัญหานั้นจะทำให้เกิดข้อบกพร่องหรือไม่? มันใช้งานได้สำหรับฉันและบน iFrame ฉันมีการเชื่อมต่อแบบไดนามิกที่สร้างโดย php ฉันกลัวข้อบกพร่องในอนาคตด้วยสิ่งนั้น ...


2
แน่นอนว่าการเลื่อน "iframe" จะมีขนาดเท่ากันทุกหน้า ดังนั้นในขณะนำทางคุณจะเห็นมันเหมือนกับการเลื่อน "หน้า"
Elton Morais

0

ปัจจุบันมีเพียง 4 วิธีที่ฉันรู้:

ข้อที่สามเท่านั้นที่สามารถแก้ไขปัญหาต่างๆได้ ตัวอย่างเช่นคุณสามารถสร้าง iFrame ตอบสนอง ; ปิดจากภายในหรือคุณสามารถสื่อสารกับมันคุณสามารถสื่อสารกับมันแต่ในการทำเช่นนั้นคุณต้องใช้ iFrame ใน Iframe และวิธีแก้ปัญหา "คุกกี้ของบุคคลที่สาม" (ไม่บังคับ)

ฉันได้สร้างบทความเกี่ยวกับเรื่องนี้โดยมีตัวอย่าง: iFrame ข้ามโดเมนที่ขับเคลื่อนด้วยเหตุการณ์


0

คุณได้พิจารณาแอตทริบิวต์ HTML5 แบบ "พอดีกับวัตถุ" แล้วหรือยัง ปรับขนาดวิดีโอ / รูปภาพไปยัง iframe แทนที่จะปรับขนาด iframe (ดีถ้าคุณจับภาพขนาดกลางที่มีความกว้าง 5,000px) ตัวเลือก "พอดี" (อื่น ๆ คือ "ปก" และ "เติม") ใช้วิธีการจัดเรียงกล่องจดหมายเพื่อให้พอดีกับแหล่งที่มาในขณะที่รักษาอัตราส่วน สำหรับการดูโดยไม่ใช้ HTML5 นอกนั้นดูเหมือนว่าจะมีโพลีฟิลล์มากมาย อันนี้ดีมาก แต่ข้อผิดพลาดในตอนท้ายของ Edge ทำให้ไม่สามารถใช้งานร่วมกับ New Nightmare ของ Microsoft ได้ประมาณหนึ่งปีแล้ว: https://github.com/anselmh/object-fit

แก้ไข: หากต้องการแก้ไขปัญหาข้ามโดเมนคุณสามารถทำงานในสคริปต์เนื้อหาส่วนขยายของ Chrome ได้ตลอดเวลาเนื่องจากคิดว่าเป็นส่วนหนึ่งของหน้าที่คุณติด iframe ไว้


0

HTTPS ลิงก์อื่นรับความสูงเป็นความสูงอัตโนมัติของ iframe

https://-a.comเนื้อหา:

 <!DOCTYPE html>
    <html>
    <head>
        <title>Test Page</title>
    </head>
    <body>
        Test Page:
        <hr/>
        <iframe id="iframe" src="https://-b.com" style="width:100%;min-height:600px;border:none;" scrolling="no" ></iframe>
        <script>
        // browser compatibility: get method for event 
        // addEventListener(FF, Webkit, Opera, IE9+) and attachEvent(IE5-8)
        var myEventMethod = 
            window.addEventListener ? "addEventListener" : "attachEvent";
        // create event listener
        var myEventListener = window[myEventMethod];
        // browser compatibility: attach event uses onmessage
        var myEventMessage = 
            myEventMethod == "attachEvent" ? "onmessage" : "message";
        // register callback function on incoming message
        myEventListener(myEventMessage, function (e) {
            // we will get a string (better browser support) and validate
            // if it is an int - set the height of the iframe #my-iframe-id
            if (e.data === parseInt(e.data)) 
                document.getElementById('iframe').height = e.data + "px";
        }, false);
        </script>
    </body>
    </html>

https://-b.com iframe เนื้อหา:

<!DOCTYPE html>
<html>
<head>
    <title>Test Iframe Content</title>
    <script type="text/javascript">
    // all content including images has been loaded
    window.onload = function() {
        // post our message to the parent
        window.parent.postMessage(
            // get height of the content
            document.body.scrollHeight
            // set target domain
            ,"*"
        )
    };
</script>
</head>
<body>
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>1
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>2
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>3
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>4
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>5
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>6
</body>
</html>

โต๊ะทำงาน:

xcom http> ycom https งาน

xcom https> ycom https WORK

xcom http> ycom http WORK

xcom https> ycom http WORK

ทดสอบภาพหน้าจอการทำงาน


-2

คุณต้องการหาความสูงของหน้าเว็บที่อยู่ใน iframe หรือไม่? ฉันมีจาวาสคริปต์ที่ใช้งานได้ซึ่งตรวจสอบความสูงของเนื้อหา iframe จากนั้นตั้งค่าความสูงของ iframe เป็นความสูงของเนื้อหา

var Height = document.getElementById('iFrameId').contentWindow.document.body.scrollHeight;

document.getElementById('iFrameId').height = Height;

อย่างไรก็ตามจะใช้ได้เฉพาะเมื่อหน้าที่คุณแสดงใน iframe อยู่บนโดเมนเดียวกัน หากไม่ใช่คุณจะไม่สามารถเข้าถึงข้อมูลที่จำเป็นได้ ดังนั้นข้อผิดพลาดการเข้าถึงถูกปฏิเสธ


ใช่ฉันลองแล้ว มันใช้งานได้ดี .. บนโดเมนเดียวกันอย่างที่คุณบอก .. บอกหน่อยว่าเบราว์เซอร์รู้ได้อย่างไรว่า 100% ในตอนแรกคำนวณความสูงได้อย่างไร? ทำไมเราไม่สามารถเข้าถึงค่าเหล่านั้นได้? Chrome จัดเก็บสิ่งนี้ในรูปแบบการคำนวณสำหรับทุกหน้าใน iframe แม้แต่ x-domain ...
Piotr Kula

ความสูงจะคำนวณขึ้นอยู่กับเนื้อหาและคุณลักษณะที่มี ความสูงขององค์ประกอบไม่แน่นอนจนกว่าจะแสดงผลเด็ก
MarioRicalde

แล้วจะรับค่าที่แสดงผลได้อย่างไร? เหมือนกับการตรวจสอบใน chrome?
Piotr Kula

-1 เนื่องจากไม่สามารถทำงานข้ามโดเมนซึ่งเป็นสิ่งที่เขาขอ
Sean Kinsey

คุณไม่สามารถรับค่าได้ ผู้ตรวจสอบสามารถทำได้เนื่องจากมีสิทธิ์ระดับ "ส่วนขยายเบราว์เซอร์" และไม่ใช่ "หน้าเว็บที่มีต้นกำเนิดอื่น"
Quentin

-2

ในการปรับขนาด iframe นี่คือสคริปต์ง่ายๆ:

สิ่งนี้อยู่ในหัว: (สิ่งนี้ถูกเขียนขึ้นสำหรับสคริปต์ php สำหรับ html เปลี่ยน "เป็น" และ \ "เป็น" ...

<script type='text/javascript'>
<!--
function resizeIframe(id){
/*
this.obj=obj
//this.obj.width=null
//this.obj.width=window.frames[\"sizeframe1\"].document.body.scrollWidth
this.obj.style.height=\"\" // for Firefox and Opera
setTimeout(\"this.obj.style.height=this.obj.contentWindow.document.body.scrollHeight+(notIE?heightOffset:0)\",10) // setTimeout required for Opera
*/

el=document.getElementById(id)
el.style.height='200px' // for Firefox and Opera
setTimeout('el.style.height=el.contentWindow.document.body.scrollHeight+\"px\"',1) // setTimeout required for Opera
}

// -->
</script>"

ส่วนท้ายของหัว

สิ่งนี้จะเกิดขึ้นในร่างกาย (โปรดจำไว้ว่าสิ่งนี้ถูกเขียนขึ้นสำหรับสคริปต์ php สำหรับ html เปลี่ยน "เป็น" และ \ "เป็น" ... )

<iframe onload='resizeIframe(this.id)' allowTransparency=\"true\" name='ccpaymentwindow' id='sizeframe1' marginwidth='1' marginheight='1' height='700' width='690' border='0' frameborder='1' scrolling='no' src='ccmslink.php?variable1=" . $variable1 . "'></iframe>

โบนัส: มีคำแนะนำด้านบน เนื่องจากถูกตั้งค่าไว้สำหรับการเขียนสคริปต์ php คุณสามารถทำอะไรได้มากมาย ... เพื่อเรียนรู้เพิ่มเติมทำเพิ่มเติม ...

กุญแจสำคัญของสิ่งนี้คือ "sizeframe1" .... สำหรับ "resizers" หลายตัวในหน้าเดียวกันให้คัดลอกสคริปต์เดียวกัน แต่เปลี่ยน id ใน iframe และชื่อในสคริปต์ในส่วนหัวและวิโอลา! คุณมีหลาย resizers ในหน้าเดียวกัน ... มันทำงานได้ดีมาก!

มีพูน.


ฉันไม่คิดว่าคุณกำลังตอบคำถามจริงที่ถาม
Andrew Barber

ใช่ - นี่คือจาวาสคริปต์ที่ใช้เพื่อปรับขนาด iframe บนโดเมนเดียวกัน ใช้ jQuery ได้ง่ายกว่ามาก สิ่งนี้จะไม่ทำงานข้ามไซต์และไม่มีอะไรแปลกใหม่ที่จะอนุญาตให้ทำได้ และไม่มีสิ่งที่เรียกว่าสคริปต์ php?!
Piotr Kula
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.