4

我有一些页面加载到父页面中的 iframe 中,我正在使用 postMessage 将子页面的高度发送给父页面,以便它可以调整 iframe 的大小。子页面非常简单,为了找到正文的高度而拥有额外的 jQuery 大小似乎是一种耻辱。但是,到目前为止,我还没有能够在直接的 JavaScript 中复制上述调用的效果。

我尝试了应用于 body 和 body.documentElement 的 scrollHeight、offsetHeight 和 clientHeight 的不同组合,但都不匹配。而且它们在不同的浏览器中非常不同,尤其是当您在大小差异很大的子文档之间切换时。以下是所有子页面的 onload 事件处理程序的实际代码:

window.onload = function() {
    alert("height(1) = " + document.body.scrollHeight + "\n" +
        "height(2) = " + document.documentElement.scrollHeight + "\n" +
        "height(3) = " + document.body.offsetHeight + "\n" +
        "height(4) = " + document.documentElement.offsetHeight + "\n" +
        "height(5) = " + document.body.clientHeight + "\n" +
        "height(6) = " + document.documentElement.clientHeight + "\n" +
        "height(7) = " + $('body').outerHeight(true)
    );
    parent.postMessage($('body').outerHeight(true) + "px", "*");
}

在每种情况下,前六个值都不匹配每个浏览器(IE8/FF/Chrome)中的第七个值。第二个是最近的,但是当从一个大的子页面切换到一个较小的页面时,它在 Chrome 中失败了——它仍然给出了前一页的大小。

我确实阅读了 jQuery 的源代码,但我的 JavaScript 还不够好,无法弄清楚它在做什么。

4

4 回答 4

0

jQuery 然后进入 cssHooks 函数,这一切都开始变得棘手。回想起来,花时间试图弄清楚它在做什么似乎毫无意义。我应该使用它。我在父页面中使用它,所以无论如何所有浏览器都会缓存它。

于 2012-04-19T12:55:11.377 回答
0

Vanilla Masonry 有一个功能 - getWH() - 从 Jquery 重构,它应该可以满足您的需求: https ://github.com/desandro/vanilla-masonry

// returns width/height of element, refactored getWH from jQuery
function getWH( elem, measure, isOuter ) {
    // Start with offset property
    var isWidth = measure !== 'height',
        val = isWidth ? elem.offsetWidth : elem.offsetHeight,
        dirA = isWidth ? 'Left' : 'Top',
        dirB = isWidth ? 'Right' : 'Bottom',
        computedStyle = getStyle( elem ),
        paddingA = parseFloat( computedStyle[ 'padding' + dirA ] ) || 0,
        paddingB = parseFloat( computedStyle[ 'padding' + dirB ] ) || 0,
        borderA = parseFloat( computedStyle[ 'border' + dirA + 'Width' ] ) || 0,
        borderB = parseFloat( computedStyle[ 'border' + dirB + 'Width' ] ) || 0,
        computedMarginA = computedStyle[ 'margin' + dirA ],
        computedMarginB = computedStyle[ 'margin' + dirB ],
        marginA, marginB;

    if ( !supportsPercentMargin ) {
        computedMarginA = hackPercentMargin( elem, computedStyle, computedMarginA );
        computedMarginB = hackPercentMargin( elem, computedStyle, computedMarginB );
    }

    marginA = parseFloat( computedMarginA ) || 0;
    marginB = parseFloat( computedMarginB ) || 0;

    if ( val > 0 ) {

        if ( isOuter ) {
            // outerWidth, outerHeight, add margin
            val += marginA + marginB;
        } else {
            // like getting width() or height(), no padding or border
            val -= paddingA + paddingB + borderA + borderB;
        }

    } else {

        // Fall back to computed then uncomputed css if necessary
        val = computedStyle[ measure ];
        if ( val < 0 || val === null ) {
            val = elem.style[ measure ] || 0;
        }
        // Normalize "", auto, and prepare for extra
        val = parseFloat( val ) || 0;

        if ( isOuter ) {
            // Add padding, border, margin
            val += paddingA + paddingB + marginA + marginB + borderA + borderB;
        }
    }

    return val;
}

[编辑] 你还需要从 vanilla-masonry.js 获取 hackPercentMargin 和 getStyle

于 2013-01-11T14:43:02.017 回答
0

您可以查看jQuery 源代码

// outerHeight and outerWidth
jQuery.fn[ "outer" + name ] = function( margin ) {
    var elem = this[0];
    return elem ?
        elem.style ?
        parseFloat( jQuery.css( elem, type, margin ? "margin" : "border" ) ) :
        this[ type ]() :
        null;
};
于 2012-04-13T15:45:38.763 回答
0
$('body').outerHeight(true) = document.body.height + document.body.marginTop + document.body.marginBottom + document.body.bordorTop + document.body.borderBottom
于 2012-04-13T15:52:14.453 回答