在没有jQuery的情况下复制jQuery的$(' body')。outerHeight(true)

时间:2012-04-13 15:42:09

标签: jquery

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

我尝试过将不同的scrollHeight,offsetHeight和clientHeight组合应用于body和body.documentElement,但没有匹配。它们在不同的浏览器中非常不同,特别是如果您在大小不同的子文档之间切换。以下是所有子页面的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 个答案:

答案 0 :(得分:0)

您可以查看jQuery source

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

答案 1 :(得分:0)

$('body').outerHeight(true) = document.body.height + document.body.marginTop + document.body.marginBottom + document.body.bordorTop + document.body.borderBottom

答案 2 :(得分:0)

jQuery然后进入cssHooks函数,它开始变得毛茸茸。经过反思,花时间试图弄清楚它在做什么似乎毫无意义;我应该用它。我在父页面中使用它,所以所有浏览器都会缓存它。

答案 3 :(得分: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;
}

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