解决js使用offsetTop滚动到指定元素位置会有误差的问题.md

1,413 阅读1分钟
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        div {

            height: 100px;
            width: 100%;
            background-color: #cccccc;
            /* margin-top: 20px; */
        }

        div:nth-child(2n) {
            background-color: #999999;

        }
    </style>
</head>

<body>
    <div style="position: fixed;z-index:10; top: 0;background-color: green;"> <button onclick="go()">去指定位置</button>
    </div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div style="position: relative;">
        <div style="position: relative;height:30px">
            <div id="div1">指定位置</div>
        </div>
    </div>
    <div>2</div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
</body>
<script>
    // offsetTop 
    // 元素距离最近开启定位父元素顶部的距离,如无开启则是距离根元素(body)的顶部的距离
    // offsetParent
    // 1)当某个页面元素及其DOM结构层次中元素都未进行进行CSS定位时(position:absolute或者relative),该元素的offsetParent属性的取值为根元素,通常为Body。

    // 2)当某个页面元素的父元素进行了CSS定位(position:absolute或者relative),则该元素的offsetParent属性取值为其父元素,该元素的各种偏移量计算(offsetTop、offsetLeft等)的参照物都为其父元素。

    // 3)当某个元素及其父元素都未进行CSS定位时(position:absolute或者relative),则该元素的offsetParent属性取值为DOM层次中距离最近,并且已做了CSS定位的上级元素。

    // 去指定位置方法
    function go() {
        //获取指定元素
        let el = document.getElementById('div1')
        // 获取该元素距离body顶部的距离
        let xh = getElementTop(el)
        // 窗口滚动到指定位置
        // window.scroll(0,xh-100)
        window.scroll({
            top: xh - 100,
            behavior: 'smooth'
        })
    }
    //获取指定元素距离body顶部的距离
    function getElementTop(el) {
        // 获取当前元素距离最近开启定位(非static)的距离
        let parentTop = el.offsetTop
        //   获取元素offsetParent
        let current = el.offsetParent
        //   进行判断是否是根元素(body),如果不是进行offsetTop的计算累加 
        while (current !== null) {
            parentTop += current.offsetTop
            current = current.offsetParent
        }
        //   是的话结束while循环 返回累加高度 ,即该元素距离body顶部的距离
        return parentTop
    }

</script>

</html>