js 中style.height和offsetHeight比較

鴨脖發表於2013-12-19

看到藍色經典論壇的一個討論帖子:

http://bbs.blueidea.com/thread-3072537-1-1.html


從兩個人的爭論中,更加深入的瞭解了style.height和offsetHeight的區別


style.height:

只能在div在行內樣式設定了height才能獲取到

例如:<div id="h" style="height:200px;">height</div>

 document.getElementById("h").style.height 能獲取到 height等於200px;並且獲取的是一個字串“200px”

但是如果:<div id="h">height</div>

在css中設定#h{height:200px;}

這時document.getElementById("h").style.height 就獲取不到height的值;


缺點:

如果height值不寫在行內樣式,style.height為undefind,無法獲取;

在高度超過範圍的情況下,style.height就是獲取的錯誤高度;

style.height只能獲取DOM把height設定在行內樣式裡面的情況(js直接設定也可);


討論:

style.height適合做自定義函式setStyle(name,value)    getComputedStyle  + currentStyle +obj.style
直接用style.height取高度程式擴充套件性很低;

可以在個大入口網站,各種小站,各種技術貼,各種程式碼分享裡等等無數地方找到js直接設定css的情況;

style.height非常明確的返回的是我設定的高,不管是js設定還是style中設定,它非常準確


1.效率:ie6沒試,除ie8外幾大主流瀏覽器上面offsetHeight速度比較快的,不過具體應用上一般不會影響,但我們儘量提高效率還是比較好的。
2.我們一般操作dom的時候是改變他表現出來的效果,因此還是offsetHeight更加合適
3.style.height獲取到的是字串,而且帶上單位的,有計算操作的情況下offsetHeight會更加方便
4.相容性上面來說,如果你物件1在兩個瀏覽器上面的offsetHeight不同,那你要設定物件2的高度的時候用的是他表現出來的高度還是style設定的高度呢?舉個例子:ie6下面容器1style設定了height:100px;然而被子物件撐大了,你要設定容器2的高度跟容器1的高度相同,那麼你是用style.height還是offsetHeight呢?



offsetHeight:

這個的優點是能獲取到css中設定的height的值,缺點是相容問題,offsetHeight在各個瀏覽器下的解釋不同。

例如:

<div id="m" style="height:100px; ">1<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />1</div>

在chrome和IE下解析就不同


缺點:

如果要獲取css的height,getComputedStyle(標準瀏覽器)和currentStyle(IE)方法顯然更好


討論:

不同瀏覽器的中offsetHeight的值不一樣,是CSS造成的,和offsetHeight沒有關係。無論,我們用offsetHeight還是style.height,目的都是獲取該物件的真實高度來進行後面的計算。但物件的高度是否一致,是CSS的責任。如果一個元素的高度網頁中顯示明明是200px,但style.height獲取的高度是100px;如果是錯誤的數值,後面的計算無從談起;

相容性問題無關offsetHeight。如果不同的瀏覽器顯示的高度不一樣,先把CSS改對;


分析jquery1.8原始碼:

function getWidthOrHeight( elem, name, extra ) {


        // Start with offset property, which is equivalent to the border-box value

        var val = name === "width" ? elem.offsetWidth : elem.offsetHeight,

                valueIsBorderBox = true,

                isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box";


        if ( val <= 0 ) {

                // Fall back to computed then uncomputed css if necessary

                val = curCSS( elem, name );

                if ( val < 0 || val == null ) {

                        val = elem.style[ name ];

                }


                // Computed unit is not pixels. Stop here and return.

                if ( rnumnonpx.test(val) ) {

                        return val;

                }


                // we need the check for style in case a browser which returns unreliable values

                // for getComputedStyle silently falls back to the reliable elem.style

                valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] );


                // Normalize "", auto, and prepare for extra

                val = parseFloat( val ) || 0;

        }


        // use the active box-sizing model to add/subtract irrelevant styles

        return ( val +

                augmentWidthOrHeight(

                        elem,

                        name,

                        extra || ( isBorderBox ? "border" : "content" ),

                        valueIsBorderBox

                )

        ) + "px";

}


裡面第一句var val = name === "width" ? elem.offsetWidth : elem.offsetHeight,別人第一選擇就用的offsetHeight,緊接著在if ( val <= 0 ) 的情況下再使用curCSS函式(也就是getComputedStyle  + currentStyle方法,自己可以看這個函式的程式碼),最後才選擇style.height


當然如果使用jquery,height();是最好的解決方法

個人認為:

height()>offsetHeight>style.height


因為比較在沒有在html和用js設定height時,style.height無法獲得height

offsetHeight在使用時注意解決相容問題

相關文章