• jQuery插件开发之windowScroll


          回首望,曾经洋洋得意的代码现在不忍直视。曾经看起来碉堡的效果现在也能稍微弄点出来。社会在往前发展,人也得向前迈进。

          参考于搜狗浏览器4.2版本首页的上下滚动效果。主要实现整个窗口的上下和左右滚动逻辑,还有很多可以拓展的空间。希望大家能多提意见与建议。

      欢迎fork项目:https://github.com/codetker/myWindowScroll, 实现的效果见http://www.梦萦无双.xyz/myWindowScroll/demo/Default.html, 应用见http://wechat.wutnews.net/Web/PhotoWall/(尚在改善中)。

    插件效果:


        实现window的上下滚动,默认绑定键盘上下按钮和鼠标滑轮
        实现window的左右滚动,默认绑定键盘左右按钮
        可附加ul li协助控制滚动
        可修改后附加缓动函数,实现多种效果,详情见缓动函数表 http://easings.net/zh-cn#easeInOutQuad

    html 结构(ZenCoding形式)

      -div.divClass
          -div.toLeftOrTop
          -div.toRightOrBottom
          -div.stageClass*n
    
        -ul.controlUl
          -li.liClass*n

        其中div.toLeftOrTop,div.toRightOrBottom,ul.controlUl可选

    调用方法(详情见demo)(按需设置参数)


    A.vertical

        $(".divClass").windowScroll({
            'choose': 0,             //垂直滚动,默认
            'verticalSpeed': 1,      //控制垂直滚动速度
            'objControlUl': 'ul.controlUl', //控制垂直滚动按钮,默认为null
            'list': '.stageClass',          //垂直滚动的对象
            'crash': true,                  //撞击底部特效
            'toTop': '.toLeftOrTop',        //向上按钮,默认为null
            'toBottom': 'toRightOrBottom',  //向下按钮,默认为null
            'liHover': 'stageSelect'        //设置当前stage的类名
        });

    B.horizontal

        $(".divClass").windowScroll({
            'choose': 1,               //水平滚动
            'horizontalSpeed': 1,      //控制水平滚动速度
            'objControlUl': 'ul.controlUl', //控制水平滚动按钮,默认为null
            'list': '.stageClass',          //水平滚动的对象
            'crash': true,                  //撞击左右特效
            'toTop': '.toLeftOrTop',        //向左按钮,默认为null
            'toBottom': 'toRightOrBottom',  //向右按钮,默认为null
            'liHover': 'stageSelect'        //设置当前page的类名
        });


    运行demo
        最简单的方法为改Default.html中jquery对应script元素的src为本地的jquery(离线)或CDN中的jquery(在线),然后双击Default.html即可
        或者配置myBoxScroll.jquery.json or package.json

    PS:代码之间耦合过强,可重复利用的很多,准备参考学长的建议按模块写个人函数库,通过模块加载注入需要使用的工具函数

          Demo代码如下:

    HTML

    <!doctype html>
    <html>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta content="" name="keywords" />
    <meta content="" name="description" />
    <meta name="author" content="codetker" />
    <head>
    <title>window对象滚动插件</title>
    <link href="style/reset.css" rel="stylesheet" type="text/css">
    <link href="style/style.css" rel="stylesheet" type="text/css">
    <script type="text/javascript" src="../src/jquery-1.9.1.min.js"></script>
    <script type="text/javascript" src="../dest/jquery.codetker.windowScroll.min.js"></script>
    </head>
    
    <body scroll="no">
        <div class="wrap" style="dispaly:block;">
            <div class="stageControl">
                <ul>
                    <li class="stageSelect">stage1</li>
                    <li>stage2</li>
                    <li>stage3</li>
                    <li>stage4</li>
                    <li>stage5</li>
                </ul>
            </div>
            <div class="toTop">Top</div>
            <div class="toBottom">Bottom</div>
            <div class="stage stage1">
                <div class="pageControl">
                    <ul>
                        <li class="pageSelect">page1</li>
                        <li>page2</li>
                        <li>page3</li>
                    </ul>
                </div>
                <div class="toLeft">Left</div>
                <div class="toRight">Right</div>
                <div class="page page1"></div>
                <div class="page page2"></div>
                <div class="page page3"></div>   
            </div>
            <div class="stage stage2"></div>
            <div class="stage stage3"></div>
            <div class="stage stage4"></div>
            <div class="stage stage5"></div>
        </div>
    <script type="text/javascript">
        $(document).ready(function() {
            $(".wrap").windowScroll({
                'choose': 0,
                'verticalSpeed': 1, 
                'objControlUl': '.wrap .stageControl',
                'list': '.wrap .stage',
                'crash': true,
                'toTop': '.toTop',
                'toBottom': '.toBottom',
                'liHover': 'stageSelect'
            });
            $(".stage1").windowScroll({
                'choose': 1,
                'horizontalSpeed': 1, 
                'objControlUl': '.stage1 .pageControl',
                'list': '.stage1 .page',
                'crash': true,
                'toLeft': '.toLeft',
                'toRight': '.toRight',
                'liHover': 'pageSelect'
            });
        });
    </script>
    </body>
    </html>
    View Code HTML

    CSS

    @charset "utf-8";
    /* CSS Document */
    /* whole */
     body{
        margin  : 0 0;
        padding : 0 0;
        height  : 100%;
        width   : 100%;
        overflow: hidden;;
     }
     .wrap{
        font-family: "微软雅黑","宋体", Times, "Times New Roman", serif;
        font-size  : 14px;
        margin     : 0 0;
        padding    : 0 0;
        height     : 100%;
        width      : 100%;
        overflow   : hidden;
     }
    /* whole end */
    
    /* stage */
     .stage,.page{
        width : 100%;
        height: 100%;
     }
     .stage1{
        background-color: #b9f579;
     }
     .stage2{
        background-color: #d87efa;
     }
     .stage3{
        background-color: #f97171;
     }
     .stage4{
        background-color: #ffc438;
     }
     .stage5{
        background-color: #9ff4d5;
     }
     .stageControl{
        position: fixed;
     }
     .stageControl ul li{
         -webkit-transition-duration: 0.3s;
         -o-transition-duration     : 0.3s;
         transition-duration        : 0.3s;
        /* 兼容低版本IE,add PIE.htc or IE-css3.htc here */
     }
     .stageSelect{
         background-color: #888 !important;
     }
    /* stage end */
    
    /* page */
     .page{
        float: left;
     }
     .page2{
        background-color: #fca172;
     }
     .page3{
        background-color: #b6befc;
     }
     .pageControl{
        position: absolute;
        left    : 200px;
     }
     .pageControl ul li{
        float   : left;
        -webkit-transition-duration: 0.3s;
         -o-transition-duration     : 0.3s;
         transition-duration        : 0.3s;
        /* 兼容低版本IE,add PIE.htc or IE-css3.htc here */
     }
     .pageSelect{
         background-color: #888 !important;
     }
    /* page end */
    
    /* left,right,top,bottom button */
     .toTop,.toBottom{
        position: fixed;
     }
     .toTop{
        top :180px;
     }
     .toBottom{
        top :220px;
     }
     .toLeft,.toRight{
         position: absolute;
     }
     .toLeft{
        left: 600px;
     }
     .toRight{
        left: 720px;
     }
     .toLeft,.toRight,.toTop,.toBottom,.pageControl ul li,.stageControl ul li{
        width : 100px;
        height: 30px;
        line-height: 30px;
        text-align : center;
        cursor: pointer;
        color : #fff;
        background-color: #aaa;
     }
     .toLeft:hover,.toRight:hover,.toTop:hover,.toBottom:hover,.pageControl ul li:hover,.stageControl ul li:hover{
        background-color: #888;
     }
    /* left,right,top,bottom button end */
    View Code CSS

    JavaScript

    /*
     * windowScroll 0.1
     * window滚动插件,上下左右,可选择是否回弹。参考搜狗欢迎页面
     * 兼容等常见浏览器
     * 借鉴搜狗4.2版http://ie.sogou.com/features4.2.html
     */
    ;(function($, window, document, undefined) {
        //定义构造函数
        var WindowObj = function(ele, opt) {
            this.$element = ele;
            this.defaults = {
                'choose': 0,
                'list': null,
                'verticalSpeed': 1,
                'horizontalSpeed': 1,
                'objControlUl': null,
                'toLeft': null,
                'toRight': null,
                'toTop': null,
                'toBottom': null,
                'crash': true,
                'liHover': null
            };
    
            this.options = $.extend({}, this.defaults, opt);
    
        };
    
        //给构造函数添加方法
        WindowObj.prototype = {
    
            //上下滚动的方法
            verticalMove: function() {
                var
                    obj = this.$element,
                    speed = this.options.verticalSpeed,
                    objControl = this.options.objControlUl,
                    controlList = $(objControl).find('li'),
                    windowHeight = $(window).height(),
                    list = this.options.list,
                    listMax = $(list).length,
                    toTop = this.options.toTop,
                    toBottom = this.options.toBottom,
                    crashButton = this.options.crash,
                    liHover = this.options.liHover,
                    stop = 0,
                    stageIndex,
                    windowobject = is_chrome();
    
    
                function setCss() {
                    $(obj).css({
                        'width': $(window).width() + 'px',
                        'height': $(window).height() * listMax + 'px'
                    });
                    $(list).css({
                        'min-width': $(window).width() + 'px',
                        'height': $(window).height() + 'px'
                    });
                }
                setCss();
    
                function markStage() {
                    getIndex();
                    $(controlList).removeClass(liHover);
                    $(controlList).eq(stageIndex).addClass(liHover);
                }
    
                function is_chrome() {
                    var is_ch = navigator.userAgent.toLowerCase().indexOf('chrome') > -1;
                    if (is_ch) {
                        //判断webkit内核,供scrollTop兼容性使用
                        return 'body';
                    } else {
                        //支持IE和FF
                        return 'html';
                    }
                }
    
    
                //阻止默认行为和冒泡
                function stopDefaultAndBubble(e) {
                    e = e || window.event;
                    if (e.preventDefault) {
                        e.preventDefault();
                    }
                    e.returnValue = false;
    
                    if (e.stopPropagation) {
                        e.stopPropagation();
                    }
                    e.cancelBubble = true;
                }
    
                //得到当前的垂直位置
                function getIndex() {
                    stageIndex = Math.round($(window).scrollTop() / windowHeight);
                }
    
                function goTop() {
                    getIndex();
                    scrollStage(windowobject, stageIndex, 1);
                }
    
                function goBottom() {
                    getIndex();
                    scrollStage(windowobject, stageIndex, -1);
                }
    
                //绑定键盘上下按键事件
                $(document).keydown(function(event) {
                    /* 绑定keycode38,即向上按钮 */
                    if (event.keyCode == 38) {
                        goTop();
    
                    } else if (event.keyCode == 40) { //绑定40,即向下按钮
                        goBottom();
                    }
                });
    
                //绑定滑轮功能的函数
                function handle(delta) {
                    getIndex();
                    if (delta < 0) {
                        scrollStage(windowobject, stageIndex, -1); //stageIndex为当前页码
                    } else {
                        scrollStage(windowobject, stageIndex, 1); //stageIndex为当前页码
                    }
    
                }
    
                //判断滑轮,解决兼容性
                function wheel(event) {
                    var delta = 0;
                    if (!event) event = window.event;
                    if (event.wheelDelta) {
                        delta = event.wheelDelta;
                        if (window.opera) delta = -delta;
                    } else if (event.detail) {
                        delta = -event.detail;
                    }
                    if (delta)
                        handle(delta); //调用执行函数
                }
    
                //注册事件
                if (window.addEventListener) {
                    window.addEventListener('DOMMouseScroll', wheel, false);
                }
                window.onmousewheel = document.onmousewheel = wheel;
    
                //绑定鼠标滚轮事件
                $(document).bind('mousedown', function(e) {
                    if (e.which == 2) { //which=2代表鼠标滚轮,即为中键
                        stopDefaultAndBubble(e);
    
                        //bugfix 搜狗浏览器的ie内核只有在定时器触发这个函数才生效
                        setTimeout(function() {
                            stopDefaultAndBubble(e);
                        }, 10);
                    }
                });
    
                //如果有ul li控制按钮
                if (objControl !== null) {
                    $(objControl).delegate('li', 'click', function() {
                        stageIndex = $(this).index();
                        scrollStage(windowobject, stageIndex, 0);
                    });
                }
    
                //如果有上下控制
                $(toTop).click(function() {
                    goTop();
                });
                $(toBottom).click(function() {
                    goBottom();
                });
    
                function scrollStage(obj, stIndex, dir) {
    
                    var
                        sIndex = stIndex,
                        windowobject = obj,
                        direction = 0 || dir,
                        target = windowHeight * sIndex;
    
                    function move() {
                        $(windowobject).animate({
                            'scrollTop': target + 'px'
                        }, 1000 * speed, function() {
                            crash(1, target, 20, 150, -1);
    
                            markStage();
                        });
                    }
    
                    function after_crash(distant, time, termin) {
                        if (distant <= 15 || time > 150) {
                            stop = 1; //停止碰撞
                            $(windowobject).animate({
                                'scrollTop': termin + 'px'
                            }, time, function() {
                                stop = 0;
                            });
                        }
                    }
    
                    //撞击函数
                    function crash(direction, termin, distant, time, aspect) {
                        if (crashButton) {
                            if (!stop) {
                                if (direction === 1) {
                                    direction = 0;
                                    if (aspect === 1) {
                                        $(windowobject).animate({
                                            'scrollTop': '-=' + distant + 'px'
                                        }, time, function() {
                                            crash(direction, termin, distant * 0.6, time, 1);
                                            after_crash(distant, time, termin);
                                        });
                                    } else {
                                        $(windowobject).animate({
                                            'scrollTop': '+=' + distant + 'px'
                                        }, time, function() {
                                            crash(direction, termin, distant * 0.6, time, -1);
                                            after_crash(distant, time, termin);
                                        });
                                    }
    
                                } else if (direction === 0) {
                                    direction = 1;
                                    if (aspect === 1) {
                                        $(windowobject).animate({
                                            'scrollTop': termin + 'px'
                                        }, time, function() {
                                            crash(direction, termin, distant * 0.6, time, 1);
                                            after_crash(distant, time, termin);
                                        });
                                    } else {
                                        $(windowobject).animate({
                                            'scrollTop': termin + 'px'
                                        }, time, function() {
                                            crash(direction, termin, distant * 0.6, time, -1);
                                            after_crash(distant, time, termin);
                                        });
                                    }
    
                                }
                            }
                        }
    
                    }
    
    
                    if (!$(windowobject).is(':animated')) {
    
                        switch (direction) {
                            case 0:
                                if ($(window).scrollTop() > target) {
                                    direction = -1;
                                    move();
                                } else if ($(window).scrollTop() == windowHeight * sIndex) {
                                    direction = 0;
                                    crash(1, target, 20, 150, -1);
                                } else {
                                    direction = 1;
                                    move();
                                }
                                break;
    
                            case 1:
                                if (sIndex === 0) {
                                    crash(1, target, 20, 150, 1);
                                } else {
                                    sIndex -= 1;
                                    target = windowHeight * sIndex;
                                    move();
                                }
                                break;
    
                            case -1:
                                if (sIndex === listMax - 1) {
                                    crash(1, target, 20, 150, -1);
                                } else {
                                    sIndex += 1;
                                    target = windowHeight * sIndex;
                                    move();
                                }
                                break;
    
                            default:
                        }
                    }
                }
    
            },
    
            //左右滚动
            horizontalMove: function() {
                var
                    obj = this.$element,
                    speed = this.options.horizontalSpeed,
                    objControl = this.options.objControlUl,
                    controlList = $(objControl).find('li'),
                    windowWidth = $(window).width(),
                    list = this.options.list,
                    listMax = $(list).length,
                    liHover = this.options.liHover,
                    toLeft = this.options.toLeft,
                    toRight = this.options.toRight,
                    crashButton = this.options.crash,
                    pageIndex;
    
                function setCss() {
                    $(obj).css({
                        'width': windowWidth * listMax + 'px',
                        'height': $(window).height() + 'px'
                    });
                    $(list).css({
                        'width': windowWidth + 'px',
                        'min-height': $(window).height() + 'px'
                    });
                }
                setCss();
    
                function markPage() {
                    getPageIndex();
                    $(controlList).removeClass(liHover);
                    $(controlList).eq(pageIndex).addClass(liHover);
                }
    
                function getPageIndex() {
                    pageIndex = (-1) * Math.round(parseInt($(obj).css('margin-left')) / windowWidth);
                }
    
                function goLeft() {
                    getPageIndex();
                    scrollPage(obj, pageIndex, 1);
                }
    
                function goRight() {
                    getPageIndex();
                    scrollPage(obj, pageIndex, -1);
                }
    
                //绑定键盘左右按键事件
                $(document).keydown(function(event) {
                    //判断event.keyCode为39(即向右按钮)
                    if (event.keyCode === 39) {
                        goRight();
                    }
                    //判断event.keyCode为37(即向左按钮
                    else if (event.keyCode === 37) {
                        goLeft();
                    }
                });
    
                //如果有ul li控制按钮
                if (objControl !== null) {
                    $(objControl).delegate('li', 'click', function() {
                        pageIndex = $(this).index();
                        scrollPage(obj, pageIndex, 0);
                    });
                }
    
                //如有有左右控制按钮
                $(toLeft).click(function() {
                    goLeft();
                });
                $(toRight).click(function() {
                    goRight();
                });
    
                function scrollPage(obj, pageIndex, dir) {
                    var
                        windowobject = obj,
                        direction = 0 || dir,
                        dist = Math.round(parseInt($(obj).css('margin-left'))), 
                        aim;
    
                    function getAim() {
                        aim = pageIndex * windowWidth * (-1);
                    }
    
                    function crash(type) {
                        if (crashButton) {
                            if (type === 'left') {
                                $(windowobject).animate({
                                    'margin-left': '+=' + '50px'
                                }, 500).animate({
                                    'margin-left': '-=' + '100px'
                                }, 500).animate({
                                    'margin-left': '+=' + '50px'
                                }, 500);
                            } else {
                                $(windowobject).animate({
                                    'margin-left': '-=' + '50px'
                                }, 500).animate({
                                    'margin-left': '+=' + '100px'
                                }, 500).animate({
                                    'margin-left': '-=' + '50px'
                                }, 500);
                            }
                        }
    
                    }
    
                    function move() {
                        $(windowobject).animate({
                                'margin-left': aim + 'px' 
                            },
                            1000 * speed,
                            function() {
                                markPage();
                            });
                    }
    
                    if (!$(windowobject).is(':animated')) {
                        switch (direction) {
    
                            case 0:
                                getAim();
                                if (dist !== aim) {
                                    move();
                                } else {
                                    direction = 0;
                                    crash('left');
                                }
                                break;
    
                            case 1:
                                if (pageIndex === 0) {
                                    crash('left');
                                } else {
                                    pageIndex -= 1;
                                    getAim();
                                    move();
                                }
                                break;
    
                            case -1:
                                if (pageIndex === (listMax - 1)) {
                                    crash('right');
                                } else {
                                    pageIndex += 1;
                                    getAim();
                                    move();
                                }
                                break;
    
                            default:
                                break;
                        }
    
                    }
                }
    
            }
        };
    
        //绑定方法到jquery对象原型上
        $.fn.windowScroll = function(options) {
    
            var windowObj = new WindowObj(this, options);
    
            if (windowObj.options.choose === 0) {
                return windowObj.verticalMove();
            } else if (windowObj.options.choose === 1) {
                return windowObj.horizontalMove();
            } else {
                //add some functions
            }
        };
    })(jQuery, window, document);
    View Code JS
  • 相关阅读:
    Java 设计模式(2)工厂模式
    Java 设计模式-六大原则
    华为机试测试- 求有序数组中最长的等差序列
    JAVA SE 基础复习-面向对象(2) static
    Java 设计模式
    Java 字符串
    jQuery源代码学习之七—队列模块queue
    jQuery源代码学习之六——jQuery数据缓存Data
    jQuery源代码学习之五——jQuery.when
    javascript源代码学习之五——jQuery.deferred
  • 原文地址:https://www.cnblogs.com/codetker/p/4643815.html
Copyright © 2020-2023  润新知