你真的會用getBoundingClientRect嗎

你真的會用getBoundingClientRect嗎?

左鵬飛 2017.09.20

本文介紹了什麼是getBoundingClientRect;以及獲取width,height的兼容性寫法;最後介紹了兩個使用場景:獲取頁面元素的位置和判斷元素是否在可視區域。

1. 什麼是getBoundingClientRect

getBoundingClientRect用於獲得頁面中某個元素的左,上,右和下分別相對瀏覽器視窗的位置。getBoundingClientRectDOM元素到瀏覽器可視範圍的距離(不包含文檔卷起的部分)。

  • 該函數返回一個Object對象,該對象有6個屬性:top,lef,right,bottom,width,height

  • 這裏的top、left和css中的理解很相似,width、height是元素自身的寬高;

  • 但是right,bottom和css中的理解有點不一樣。right是指元素右邊界距窗口最左邊的距離,bottom是指元素下邊界距窗口最上面的距離。

圖1

// 獲取元素
var box=document.getElementById('box');

// 元素上邊距離頁面上邊的距離
alert(box.getBoundingClientRect().top);

// 元素右邊距離頁面左邊的距離
alert(box.getBoundingClientRect().right); 

// 元素下邊距離頁面上邊的距離
alert(box.getBoundingClientRect().bottom);

// 元素左邊距離頁面左邊的距離
alert(box.getBoundingClientRect().left);

圖2

2.兼容性

getBoundingClientRect()最先是IE的私有屬性,現在已經是一個W3C標準。所以你不用當心瀏覽器兼容問題,不過還是有區別的:IE只返回top,lef,right,bottom四個值,不過可以通過以下方法來獲取width,height的值

var ro = object.getBoundingClientRect();
var Width = ro.right - ro.left;
var Height = ro.bottom - ro.top;

//兼容所有瀏覽器寫法:

var ro = object.getBoundingClientRect();
var Top = ro.top;
var Bottom = ro.bottom;
var Left = ro.left;
var Right = ro.right;
var Width = ro.width||Right - Left;
var Height = ro.height||Bottom - Top;

3. 用getBoundingClientRect()來獲取頁面元素的位置

以前絕大多數的時候使用下面的代碼來獲取頁面元素的位置:

var _x = 0, _y = 0;
do{
	_x += el.offsetLeft;
	_y += el.offsetTop;
}
while(el=el.offsetParent);

return {x:_x,y:_y}

這裏有個”offsetParent”問題,所以要寫很多兼容的代碼。

有了getBoundingClientRect這個方法,獲取頁面元素的位置就簡單多了,

var X= this.getBoundingClientRect().left+document.documentElement.scrollLeft;

var Y =this.getBoundingClientRect().top+document.documentElement.scrollTop;

4. 判斷元素是否在可視區域

以前的辦法是通過各種offset判斷元素是否可見。

me.on('onload', function () {
    var hasDot = false;
    function scrollHandler() {
        var elOffsetTop = me.$el.offset().top;
        var elHeight = me.$el.height();
        var wHeight = $(window).height();
        var scrollTop = $(window).scrollTop();
        if (scrollTop + wHeight >= elOffsetTop + elHeight) {
            if (!hasDot) {
                me.fire('moduleShow');
            }
            hasDot = true;
        }
    }
    // 知識圖譜推薦模塊展現PV/UV(模塊底部露出頁面視爲被展現)
    $(window).on('scroll.kgrecommend', scrollHandler);
    // 先執行一遍
    scrollHandler();
});

getBoundingClientRect是獲取可視區域相關位置信息的,使用這個屬性來判斷更加方便:

function isElementInViewport (el) {
    var rect = el.getBoundingClientRect();
    return (
        rect.top >= 0 &&
        rect.left >= 0 &&
        rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */
        rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
    );
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章