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


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

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

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

    <!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会设置垂直滚动条,让它滚动到顶部,效果如下:

     writer by:大沙漠 QQ:22969969

    很多网站右下角有一个滚动到顶部就可以用这个来实现,完美兼容所有网站,这个得感谢完美jQuery的兼容性。

    源码分析


    代码实现如下

    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实现如下:

    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对象才可以

  • 相关阅读:
    Directx 3D编程实例:多个3D球的综合Directx实例
    利用组策略禁用Oultook 各个版本的缓存模式!
    node-mongo-native1.3.19连接mongo的最优方法
    BT5之网络配置
    BT5之配置笔记
    Linux常用命令大全
    Linux下的基本网络配置
    SQLMAP系列教程
    重燃你的PHP安全分析之火
    Metasploit渗透测试魔鬼训练营
  • 原文地址:https://www.cnblogs.com/greatdesert/p/11907275.html
Copyright © 2020-2023  润新知