HTML元素坐標定位,這些知識點得掌握


文檔坐標和視口坐標

    視口坐標是相對於窗口的坐標,而文檔坐標是相對於整個文檔而言。例如,在文檔坐標中如果一個元素的相對於文檔的Y坐標是200px,並且用戶已經把瀏覽器向下滾動了75px,那么視口坐標中元素的Y坐標為200px – 75px = 125px。
    如何獲取瀏覽器滾動條的位置?Window對象的pageXOffset和pageYOffset屬性在所有瀏覽器中提供這些值,除IE8以及更早的版本。IE和所有現代瀏覽器也可以通過scrollLeft和scrollTop屬性獲取滾動條位置。

    下面代碼的getScrollOffsets方法獲取滾動條位置:

//以一個對象的x和y屬性放回滾動條的位置
function getScrollOffsets(w){
    w = w || window;
    //除了IE 8以及更早的版本以外,其他瀏覽器都支持
    if(w.pageXOffset != null) return {x: w.pageXOffset, y: w.pageYOffset};
    //對標准模式下的IE
    var d = w.document;
    if(document.compatMode == "CSS1Compat")
        return {x: d.documentElement.scrollLeft, y: d.documentElement.scrollTop};
    //對怪異模式下的瀏覽器
    return { x: d.body.scrollLeft, y: d.body.scrollTop};
}

    有時候能夠判定視口的尺寸也是非常有用的,下面的代碼簡便地查詢視口尺寸:

//作為一個對象的w和h屬性返回視口的尺寸
function getViewportSize(w){
    //使用指定的窗口, 如果不帶參數則使用當前窗口
    w = w || window;

    //除了IE8及更早的版本以外,其他瀏覽器都能用
    if(w.innerWidth != null)
        return {w: w.innerWidth, h: w.innerHeight};

    //對標准模式下的IE(或任意瀏覽器)
    var d = w.document;
    if(document.compatMode == "CSS1Compat")
        return {w: d.documentElement.clientWidth, h: d.documentElement.clientHeight};

    //對怪異模式下的瀏覽器
    return {w: d.body.clientWidth, h: d.body.clientHeight};
}

    上面的兩個例子已經使用到scrollLeft、scrollTop、clientWidth、clientHeight。 scrollLeft和scrollTop獲取滾動條位置,而clientWidth和clientHeight獲取對象的尺寸。

查詢元素的幾何尺寸

    判定一個元素的尺寸和位置最簡單的方法是調用它的getBoundingClientRect()方法。該方法是在IE5中引入的,而現在當前的所有瀏覽器都實現了。它不需要參數,返回left、right、top、bottom屬性的對象。
    這個方法返回元素在視口坐標中的位置。為了轉換為甚至用戶滾動瀏覽器窗口以后任然有效的文檔坐標,需要加上滾動偏移量:

//元素相對於文檔的坐標位置
function getElementRect(e){
    var box = e.getBoundingClientRect();
    var offsets = getScrollOffsets();
    var x = box.left + offsets.x;
    var y = box.top + offsets.y;

    return {x:x, y: y};
}

    在很多瀏覽器中,getBoundingClientRect()返回的對象還包括width和height屬性。但在原始的IE中未實現。可以這樣計算元素的width和height:

//元素尺寸
function getElementSize(e){
    var box = getElementRect(e);
    var w = box.width || box.right - box.left;
    var h = box.height || box.bottom - box.top;

    return {w: w, h: h};
}

滾動元素

    之前的getScrollOffsets方法可以查詢滾動條的位置。該例子的scrollLeft和scrollTop屬性可以用來設置讓瀏覽器滾動,但有一種更簡單的方法從Javascript最早時期開始支持的。Window對象的scrollTop()方法接口一個點的X和Y坐標(文檔坐標),並作為滾動條的偏移量設置它們。下面代碼滾動瀏覽器到文檔最下面的頁面可見:

//滾動到瀏覽器最底部
function scrollToBottom(){
    //獲取文檔和視口的高度
    var documentHeight = document.documentElement.offsetHeight;
    var viewportHeight = window.innerHeight; //或使用上面的getViewPortSize()方法

    //然后,滾動讓最后一頁在視口中可見
    window.scrollTo(0, documentHeight - viewportHeight);
}

    Window的scrollBy方法和scroll()和scrollTo()類似,但是它的參數是相對的,並在當前滾動條的偏移量上增加。例如,快速閱讀者可能會喜歡這樣:   

javascript:void setInterval(function(){scrollBy(0, 10)}, 200);

    如果想讓某個元素在文檔中可見,可以利用getBoundingClientRect()計算元素的位置,並轉換為文檔坐標,然后使用scrollTo()方法達到目的。但在需要顯示Html元素上調用scrollIntoView()方法更方便。
    scrollIntoView()的行為與設置window.location.hash為一個命名錨點的名字后瀏覽器產生的行為類似。

元素尺寸、位置和溢出

    任何HTML元素的只讀屬性offsetWidth和offsetHeight以CSS像素返回它的屏幕尺寸。返回的尺寸包含元素的邊框和內邊距,除去了外邊距。
    所有HTML元素擁有offsetLeft和offsetTop屬性來返回元素的X和Y坐標。這些值是文檔坐標,並直接指定元素的位置。當對於已定位元素的后代元素和一些其他元素,這些屬性返回的坐標是相對於祖先元素的而非文檔。
offsetParent屬性指定這些屬性所相對的父元素。如果offsetParent為null,這些屬性都是文檔坐標,因此,一般來說,用offsetLeft和offsetTop來計算元素e的位置需要一個循環:

//計算元素位置
function getElementPosition(e){
    var x = 0, y = 0;
    while(e != null){
        x += e.offsetLeft;
        y += e.offsetTop;
        e = e.offsetParent;
    }

    return {x: x, y: y };
}

    getElementPosition函數也不總是計算正確的值,下面看如何修復它。除了這些名字以offset開頭的屬性以外,所有的文檔元素定義了其他兩組屬性,名字一組以client開頭,另一組以scroll開頭。即每個元素都有以下這些屬性:

offsetWidth

clientWidth scrollWidth
offsetHeight clientHeight crollHeight
offsetLeft clientLeft scrollLeft
offsetTop clientTop scrollTop
offsetParent    

    為了理解client和scroll屬性,你需要知道元素的實際內容可能比分配用來容納的盒子更大,因此單個元素可能有滾動條。內容區域是視口,就像瀏覽器窗口,當實際內容比視口大,需要把元素滾動套位置考慮進去。

    clientWidth和clientHeight類似offsetWidth和offsetHeight,區別在於它們不包含邊框大小。只包含內容和內邊距。同時,如果瀏覽器在內邊距和邊框之間添加了滾動條,clientWidth和clientHeight不包含滾動條尺寸。在文檔的根元素上查詢這些屬性時,它們的返回值和窗口的innerWidth和innerHeight屬性值相等。

    clientLeft和clientTop屬性沒什么用:它們返回元素的內邊距的外邊框和它的邊框的外邊緣之間的水平距離和垂直距離。
    scrollWidth和scrollHeight是元素的內容區域加上它的內邊距再加上任何溢出內容的尺寸。當內容正好和內容區域匹配沒溢出時,這些屬性與clientWidth和clientHeight相等。有溢出時,包含了溢出的內容尺寸。

     scollLeft和scrollTop指定元素滾動條的位置。在getScrollOffsets()方法中查詢過它們。注意,scrollLeft和scrollTop是可寫的,通過設置它們來讓元素中的內容滾動(HTML元素並沒有類似Window對象的scrollTo()方法。

DEMO

    下面代碼介紹了前面幾個函數的使用:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script type="text/javascript">
            //以一個對象的x和y屬性放回滾動條的位置
            function getScrollOffsets(w){
                w = w || window;
                //除了IE 8以及更早的版本以外,其他瀏覽器都支持
                if(w.pageXOffset != null) return {x: w.pageXOffset, y: w.pageYOffset};
                //對標准模式下的IE
                var d = w.document;
                if(document.compatMode == "CSS1Compat")
                    return {x: d.documentElement.scrollLeft, y: d.documentElement.scrollTop};
                //對冠以模式下的瀏覽器
                return { x: d.body.scrollLeft, y: d.body.scrollTop};
            }

            //作為一個對象的w和h屬性返回視口的尺寸
            function getViewportSize(w){
                //使用指定的窗口, 如果不帶參數則使用當前窗口
                w = w || window;

                //除了IE8及更早的版本以外,其他瀏覽器都能用
                if(w.innerWidth != null)
                    return {w: w.innerWidth, h: w.innerHeight};

                //對標准模式下的IE(或任意瀏覽器)
                var d = w.document;
                if(document.compatMode == "CSS1Compat")
                    return {w: d.documentElement.clientWidth, h: d.documentElement.clientHeight};

                //對怪異模式下的瀏覽器
                return {w: d.body.clientWidth, h: d.body.clientHeight};
            }

            //元素相對於文檔的坐標位置
            function getElementRect(e){
                var box = e.getBoundingClientRect();
                var offsets = getScrollOffsets();
                var x = box.left + offsets.x;
                var y = box.top + offsets.y;

                return {x:x, y: y};
            }

            //元素尺寸
            function getElementSize(e){
                var box = getElementRect(e);
                var w = box.width || box.right - box.left;
                var h = box.height || box.bottom - box.top;

                return {w: w, h: h};
            }

            //滾動到瀏覽器最底部
            function scrollToBottom(){
                //獲取文檔和視口的高度
                var documentHeight = document.documentElement.offsetHeight;
                var viewportHeight = window.innerHeight; //或使用上面的getViewPortSize()方法

                //然后,滾動讓最后一頁在視口中可見
                window.scrollTo(0, documentHeight - viewportHeight);
            }

            //計算元素位置
            function getElementPosition(e){
                var x = 0, y = 0;
                while(e != null){
                    x += e.offsetLeft;
                    y += e.offsetTop;
                    e = e.offsetParent;
                }

            return {x: x, y: y };
            }
        </script>
    </head>
    <body>
        <button id="scrolltoBottomBtn">滾動到瀏覽器</button>
        <div style="height: 400px; background: red;">

        </div>
        <button id="btn">獲取滾動條位置</button>
        <button id="viewportBtn">獲取視口尺寸</button>
        <button id="eleRectBtn">元素文檔坐標</button>
        <script type="text/javascript">
            var btn = document.getElementById("btn");
            btn.onclick = function(event){
            console.log(getScrollOffsets());
            }

            var viewportBtn = document.getElementById("viewportBtn");
            viewportBtn.onclick = function(event){
            console.log(getViewportSize());
            }

            var eleRectBtn = document.getElementById("eleRectBtn");
            eleRectBtn.onclick = function(eevent){
            console.log(getElementRect(this));
            }

            var scrolltoBottomBtn = document.getElementById("scrolltoBottomBtn");
            scrolltoBottomBtn.onclick = function(){
            scrollToBottom();
            }
        </script>
    </body>
</html>

   

    如果本篇內容對大家有幫助,請點擊頁面右下角的關注。如果覺得不好,也歡迎拍磚。你們的評價就是博主的動力!下篇內容,敬請期待!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM