jQuery 源码解析(二十八) 样式操做模块 scrollLeft和scrollTop详解

scrollLeft和scrollTop用于获取/设置滚动条的,以下:html

  • scrollLeft(val)  ;读取或设置整个页面的水平滚动条距离
  • scrollTop(val)  ;读取或设置整个页面的垂直滚动条距离

若是没有传入val值则获取滚动条距离,若是有设置val则标识设置滚动条距离,仍是举个栗子,以scrollTop为例,以下:node

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="http://libs.baidu.com/jquery/1.7.1/jquery.min.js"></script>
    <style>
        *{margin:0;padding:0;}
        button{margin:1px 0;}
        div{margin:20px;width: 200px;height: 180px;position: relative;padding-top: 20px;background: #c38;}
        h1{margin:10px;color: #333;}
    </style>
</head>
<body>
    <br/>
    <p id="result">结果:<span></span></p>
    <button id="b1">获取垂直滚动条距离</button><br/>
    <button id="b2">回到首页</button>
    <br/><br/>
    <script>
        $('#b1').click(()=>{                        //获取滚动条距离
            $('span').text( $(window).scrollTop() )
        })
        $('#b2').click(()=>{                        //设置垂直滚动条滚动到顶部
            $(window).scrollTop(0)
        })
        //这里先新增一个文档碎片,而后添加50个p标签,最后添加到body子节点的最前面,以模拟滚动条
        {
            let i=1,fragments=document.createDocumentFragment()
            while(i<=50){
                let p = document.createElement('p');
                p.innerHTML = i++;
                fragments.append(p)
            }
            document.body.insertBefore(fragments,document.body.childNodes[0])
        }
    </script>    
</body>
</html>

当咱们点击按钮1时将获取当前垂直滚动条的距离,并将结果添加到span里面,点击按钮2会设置垂直滚动条,让它滚动到顶部,效果以下:jquery

 writer by:大沙漠 QQ:22969969app

不少网站右下角有一个滚动到顶部就能够用这个来实现,完美兼容全部网站,这个得感谢完美jQuery的兼容性。源码分析

 

源码分析网站


代码实现以下this

jQuery.each( ["Left", "Top"], function( i, name ) {    //在jQuery.fn加上.scrollLeft()和.scrollTop()方法     对于scrollLeft来讲,i为0,对于scrollTop来讲,i为1
    var method = "scroll" + name;

    jQuery.fn[ method ] = function( val ) {                //挂在实例上面
        var elem, win;

        if ( val === undefined ) {                        //若是没有传入val参数
            elem = this[ 0 ];

            if ( !elem ) {                                //若是没有匹配元素
                return null;                                //则返回null
            }

            win = getWindow( elem );                    //获取window对象,若是参数elem是window对象,则返回window对象,不然返回false

            // Return the scroll offset
            return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
                jQuery.support.boxModel && win.document.documentElement[ method ] ||
                    win.document.body[ method ] :
                elem[ method ];                            //用于读取window对象、document对象、元素的滚动偏移
        }
        //执行到这里,则表示是设置滚动了
        // Set the scroll offset
        return this.each(function() {                    //遍历匹配元素,设置每一个元素的滚动偏移
            win = getWindow( this );

            if ( win ) {                                //若是是window对象,则调用scrollTo()滚动到执行的位置,该方法两个参数都是必须的。
                win.scrollTo(
                    !i ? val : jQuery( win ).scrollLeft(),    //这两个参数是必填的
                     i ? val : jQuery( win ).scrollTop()
                );

            } else {
                this[ method ] = val;                    //不然设置元素的scrollLeft、scrollTop属性。
            }
        });
    };
});

getWindow实现以下:spa

function getWindow( elem ) {
    return jQuery.isWindow( elem ) ?
        elem :                                         //若是是elem是window对象,则直接返回elem
        elem.nodeType === 9 ?
            elem.defaultView || elem.parentWindow : //不然若是elem表示整个文档,则返回elem.defaultView(即window对象),不然返回elem.parentWindow,若是elem.parentWindow不存在则返回false
            false;
}

从源码能够发现,若是是操做滚动条的话,就须要匹配window或documetn对象才能够code

相关文章
相关标签/搜索