jquery lấy chiều cao của nội dung iframe khi được tải


84

Tôi có một trang Trợ giúp, help.php mà tôi đang tải bên trong iframe trong main.php Làm cách nào để có được chiều cao của trang này sau khi nó được tải trong iframe?

Tôi đang hỏi điều này bởi vì tôi không thể định dạng chiều cao của iframe thành 100% hoặc tự động. Đó là lý do tại sao tôi nghĩ rằng tôi cần sử dụng javascript .. Tôi đang sử dụng jQuery

CSS:

body {
    margin: 0;
    padding: 0;
}
.container {
    width: 900px;
    height: 100%;
    margin: 0 auto;
    background: silver;
}
.help-div {
    display: none;
    width: 850px;
    height: 100%;
    position: absolute;
    top: 100px;
    background: orange;
}
#help-frame {
    width: 100%;
    height: auto;
    margin:0;
    padding:0;
}

JS:

$(document).ready(function () {
    $("a.open-help").click(function () {
        $(".help-div").show();
        return false;
    })
})

HTML:

<div class='container'>
    <!-- -->
    <div class='help-div'>
        <p>This is a div with an iframe loading the help page</p>
        <iframe id="help-frame" src="../help.php" width="100%" height="100%" frameborder="1"></iframe>
    </div>  <a class="open-help" href="#">open Help in iFrame</a>

    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
</div>

Nội dung của iFrame có đến từ cùng một miền với trang mà nó ở trong đó không?
Andrew

vâng, nó là andrew, tôi muốn sử dụng iFrame vì tôi sử dụng neo trong trang trợ giúp
FFish

Câu trả lời:


102

ok, cuối cùng tôi đã tìm thấy một giải pháp tốt:

$('iframe').load(function() {
    this.style.height =
    this.contentWindow.document.body.offsetHeight + 'px';
});

Vì một số trình duyệt (Safari và Opera cũ hơn) báo cáo quá trình tải hoàn tất trước khi CSS hiển thị, bạn cần đặt Thời gian chờ vi mô và bỏ trống và gán lại src của iframe.

$('iframe').load(function() {
    setTimeout(iResize, 50);
    // Safari and Opera need a kick-start.
    var iSource = document.getElementById('your-iframe-id').src;
    document.getElementById('your-iframe-id').src = '';
    document.getElementById('your-iframe-id').src = iSource;
});
function iResize() {
    document.getElementById('your-iframe-id').style.height = 
    document.getElementById('your-iframe-id').contentWindow.document.body.offsetHeight + 'px';
}

giải pháp này hoạt động tuyệt vời như ở trên chỉ nhận được kích thước từ iframe cocntent trong container trong khi điều này được các realkích thước
rickyduck

2
Tôi tin rằng sự kiện trigger tải trên vòng lặp cùng một sự kiện do đó, một setTimout của 1 mili giây sẽ làm việc chỉ là tốt
George Mauer

hhmmm Có ai biết cách lấy chiều cao của iframe bị ẩn tại thời điểm tải trang gốc không. Phương pháp này mang lại 0.
JT ...

1
Bạn có thể muốn documentchiều cao, không phải bodychiều cao. Sử dụng jQuery, bạn có thể lấy nó $(this.contentWindow.document).height().
vpiTriumph

Đến phiên bản cũ hơn, iframe.contentDocument.body.offsetHeight sẽ hoạt động. stackoverflow.com/questions/2684693/…
user1087079

50

Câu trả lời ít phức tạp hơn là sử dụng .contents()để lấy iframe. Tuy nhiên, điều thú vị là nó trả về một giá trị khác với những gì tôi nhận được bằng cách sử dụng mã trong câu trả lời ban đầu của mình, do phần đệm trên phần thân, tôi tin.

$('iframe').contents().height() + 'is the height'

Đây là cách tôi đã thực hiện cho giao tiếp giữa nhiều miền, vì vậy tôi e rằng nó có thể phức tạp không cần thiết. Đầu tiên, tôi sẽ đặt jQuery bên trong tài liệu của iFrame; điều này sẽ tiêu tốn nhiều bộ nhớ hơn, nhưng sẽ không làm tăng thời gian tải vì tập lệnh chỉ cần được tải một lần.

Sử dụng jQuery của iFrame để đo chiều cao của phần thân iframe của bạn càng sớm càng tốt (onDOMReady) và sau đó đặt băm URL thành chiều cao đó. Và trong tài liệu mẹ, hãy thêm một onloadsự kiện vào thẻ iFrame sẽ xem xét vị trí của iframe và trích xuất giá trị bạn cần. Vì onDOMReady sẽ luôn xảy ra trước sự kiện tải của tài liệu, bạn có thể khá chắc chắn rằng giá trị sẽ được giao tiếp chính xác mà không có điều kiện chạy đua làm phức tạp mọi thứ.

Nói cách khác:

... trong Help.php:

var getDocumentHeight = function() {
    if (location.hash === '') { // EDIT: this should prevent the retriggering of onDOMReady
        location.hash = $('body').height(); 
        // at this point the document address will be something like help.php#1552
    }
};
$(getDocumentHeight);

... và trong tài liệu mẹ:

var getIFrameHeight = function() {
    var iFrame = $('iframe')[0]; // this will return the DOM element
    var strHash = iFrame.contentDocument.location.hash;
    alert(strHash); // will return something like '#1552'
};
$('iframe').bind('load', getIFrameHeight );

Xin chào Andrew cho đến nay sự giúp đỡ rất tốt ở đây. content () hoạt động tốt, nhưng tôi vẫn cần kiểm tra nó bằng bộ điều chỉnh băng thông. Có thể bạn có thể sử dụng thuộc tính innerHeight (). Tôi gặp sự cố trong FF (OSX) khi sử dụng giải pháp của bạn đưa chiều cao vào hàm băm. FF dường như tiếp tục tải hàm getDocumentHeight () trong một vòng lặp vô hạn? Safari vẫn ổn ..
FFish

Hấp dẫn. Tôi đã thêm một kiểm tra ngăn việc thiết lập băm nếu đã có giá trị ở đó. Bạn có thể cần phải tinh chỉnh này nếu bạn đang tải Help.php với một giá trị băm (ví dụ <iframe src="../Help.php#introduction" />)
Andrew

Nhân tiện, Giả sử bạn có thể điều chỉnh sự khác biệt về chiều cao, bạn có thể không cần sử dụng hàm băm để giao tiếp với iframe. Nếu bạn sử dụng phương thức băm, thì việc đưa sleep(5)tệp Help.php của bạn cũng nên là một cách tốt để kiểm tra mọi điều kiện cuộc đua. Nếu iframe bằng cách nào đó kích hoạt onLoadtrước đó onDOMReady, nó sẽ hiển thị ở đây.
Andrew

23

Tôi thấy những thứ sau hoạt động trên Chrome, Firefox và IE11:

$('iframe').load(function () {
    $('iframe').height($('iframe').contents().height());
});

Khi nội dung Iframes được tải xong, sự kiện sẽ kích hoạt và nó sẽ đặt chiều cao của khung nội tuyến thành chiều cao của nội dung. Điều này sẽ chỉ hoạt động cho các trang trong cùng một tên miền với IFrame.


hoạt động tốt nhưng đối với chiều rộng, tôi phải làm như thế này hoặc nội dung bị cắt $ ('iframe'). width ($ ('iframe'). nội dung (). width () + 30);
Geomorillo

@AminGhaderi Hoạt động tốt đối với tôi trong firefox 40.0.3
mixkat

@mixkat Tôi tải một trang web trong iframe thông qua giải pháp này và tất cả các giải pháp trong chủ đề này nhưng đối với tôi không hoạt động! tôi nghĩ rằng các giải pháp này hoạt động cho một trang và không hoạt động khi chúng tôi tải hoàn chỉnh một trang web vào iframe. tiếng anh của tôi rất tệ, tôi hy vọng bạn sẽ hiểu.
Amin Ghaderi

@AminGhaderi nếu tôi hiểu đúng, bạn đang mong đợi điều này hoạt động cho mọi trang trong trang web của bạn nhưng tất nhiên điều này sẽ không hoạt động cho tất cả các trang vì nó chỉ chạy một lần khi bạn tải khung. Vì vậy, nó sẽ hoạt động tốt cho trang đầu tiên nhưng sau đó nếu bạn muốn nó hoạt động cho các trang dài hơn, bạn sẽ phải thực hiện lại bằng cách tải lại khung với trang mới hoặc bằng cách gọi nội dung. Nhấn vào một số điểm khác trong dòng chảy của bạn
mixkat

9

Mã để thực hiện việc này mà không có jQuery ngày nay rất tầm thường:

const frame = document.querySelector('iframe')
function syncHeight() {
  this.style.height = `${this.contentWindow.document.body.offsetHeight}px`
}
frame.addEventListener('load', syncHeight)

Để hủy bỏ sự kiện:

frame.removeEventListener('load', syncHeight)

3
Đẹp và đơn giản! Rất tiếc, không hoạt động cho iframe tên miền chéo :(
TimoSolo

3
Vâng, may mắn ở đó. Tôi sẽ tận dụng thư viện iframe-resizer cho điều đó. Tất nhiên, bạn cần phải kiểm soát cả hai miền để nó hoạt động.
cchamberlain

6

Bạn không cần jquery bên trong iframe để làm điều này, nhưng tôi sử dụng nó vì mã đơn giản hơn nhiều ...

Đặt cái này vào tài liệu bên trong iframe của bạn.

$(document).ready(function() {
  parent.set_size(this.body.offsetHeight + 5 + "px");  
});

đã thêm năm ở trên để loại bỏ thanh cuộn trên các cửa sổ nhỏ, nó không bao giờ hoàn hảo về kích thước.

Và điều này bên trong tài liệu mẹ của bạn.

function set_size(ht)
{
$("#iframeId").css('height',ht);
}

Điều này cũng sẽ không hoạt động nếu bạn đang hiển thị một tệp PDF trong iframe.
Jason Foglia

Xin lỗi nhưng ví dụ "bên trong khung" của bạn rõ ràng là dựa trên jQuery.
T-moty

4

đây là câu trả lời chính xác phù hợp với tôi

$(document).ready(function () {
        function resizeIframe() {
            if ($('iframe').contents().find('html').height() > 100) {
                $('iframe').height(($('iframe').contents().find('html').height()) + 'px')
            } else {
                setTimeout(function (e) {
                    resizeIframe();
                }, 50);
            }
        }
        resizeIframe();
    });

4

một lớp lót đơn giản bắt đầu với chiều cao tối thiểu mặc định và tăng lên kích thước nội dung.

<iframe src="http://url.html" onload='javascript:(function(o){o.style.height=o.contentWindow.document.body.scrollHeight+"px";}(this));' style="height:200px;width:100%;border:none;overflow:hidden;"></iframe>



1

Đây là một giải pháp miễn phí của jQuery có thể hoạt động với SPA bên trong iframe

document.getElementById('iframe-id').addEventListener('load', function () {
  let that = this;
  setTimeout(function () {
    that.style.height = that.contentWindow.document.body.offsetHeight + 'px';
  }, 2000) // if you're having SPA framework (angularjs for example) inside the iframe, some delay is needed for the content to populate
});

1

Đây là cách sử dụng không cần jquery thân thiện với ES6 của tôi

document.querySelector('iframe').addEventListener('load', function() {
    const iframeBody = this.contentWindow.document.body;
    const height = Math.max(iframeBody.scrollHeight, iframeBody.offsetHeight);
    this.style.height = `${height}px`;
});
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.