jQuery插件windowScroll实现单屏滚动特效


Posted in Javascript onJuly 14, 2015

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

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

      代码如下:

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="js/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="js/jquery.codetker.windowScroll.js"></script>
</head>

<body scroll="no">
  <div class="wrap" style="dispaly:block;">
    <div class="stageControl">
      <ul>
        <li>stage1</li>
        <li>stage2</li>
        <li>stage3</li>
        <li>stage4</li>
        <li>stage5</li>
      </ul>
    </div>
    <div class="stage stage1">
      <div class="pageControl">
        <ul>
          <li>page1</li>
          <li>page2</li>
          <li>page3</li>
        </ul>
      </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' : 2, //控制垂直滚动速度
      'horizontalSpeed' : 1,
      'objControlUl': '.wrap .stageControl'
    });
    $(".stage1").windowScroll({
      'choose': 1,
      'verticalSpeed' : 1,
      'horizontalSpeed' : 1,//控制水平滚动速度
      'objControlUl': '.stage1 .pageControl'
    });
  });
</script>
</body>
</html>

CSS

@charset "utf-8";
/* CSS Document */
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;
}

.stage,.page{
  width: 100%;
  height: 100%;
}
.stage1{
  background-color:red;
}
.stage2{
  background-color:#fff;
}
.stage3{
  background-color:yellow;
}
.stage4{
  background-color:green;
}
.stage5{
  background-color:blue;
}
.page{
  float: left;
}
.page2{
  background-color: #666;
}
.page3{
  background-color: #ddd;
}
.stageControl{
  position: fixed;
}
.stageControl ul li{
  width: 100px;
  height: 30px;
  line-height: 30px;
  text-align: center;
  cursor: pointer;
}
.stageControl ul li:hover{
  color: blue;
}
.pageControl{
  position: fixed;
  left: 200px;
}
.pageControl ul li{
  float: left;
  width: 50px;
  height: 25px;
  line-height: 25px;
  text-align: center;
  cursor: pointer;
}
.pageControl ul li:hover{
  color: blue;
}

JavaScript

/*
 * windowScroll 0.1
 * window滚动插件,上下左右,可选择是否回弹。参考搜狗欢迎页面
 * 兼容IE,FF,Chrome等常见浏览器
 * 借鉴搜狗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,//默认为上下
       'verticalSpeed' : 1,
       'horizontalSpeed' : 1,
       'objControlUl': null
     },
   
     this.options=$.extend({},this.defaults,opt );

    //阻止默认行为和冒泡,这里可以定义多个方法都要用到的函数
    this.stopDefaultAndBubble=function(e){
      e=e||window.event;
      if (e.preventDefault) {
        e.preventDefault();
      }
      e.returnValue=false;

      if (e.stopPropagation) {
        e.stopPropagation();
      }
      e.cancelBubble=true;
    }

    this.setSize=function(ele){
      $(ele).css({
        'width':$(window).outerWidth()+'px'
      });
      //自动判断元素是否存在,对undefined赋css属性无意义
      $(ele).children('.stage').css({
        'width':$(window).outerWidth()+'px',
        'height':$(window).outerHeight()+'px'
      });
      $(ele).children('.page').css({
        'width':$(window).outerWidth()+'px',
        'height':$(window).outerHeight()+'px'
      });
    }
   }

   //给构造函数添加方法
   WindowObj.prototype={

     //上下滚动的方法
     verticalMove:function(){
       var obj=this.$element; //最外层对象
       var speed=this.options.verticalSpeed;
       var objControl=this.options.objControlUl;//控制按钮

       var windowHeight=$(window).height();
       var list=$(obj).children('.stage');
       var listMax=$(list).length;

       var is_chrome=navigator.userAgent.toLowerCase().indexOf('chrome')>-1;
       if(is_chrome){
         //判断webkit内核,供scrollTop兼容性使用
         windowobject='body';
       }else{
         //支持IE和FF
         windowobject='html';
       }
       var stop=0;

       //均设置为windows大小
       this.setSize(obj);

       //得到当前的垂直位置
       var stageIndex;
       function getIndex(){
         stageIndex=Math.round($(window).scrollTop()/windowHeight);
       } 

       //绑定键盘上下按键事件
       $(document).keydown(function(event) {
         /* 绑定keycode38,即向上按钮 */
         if (event.keyCode==38) {
           getIndex();
          setTimeout(function(){
            scrollStage(windowobject,stageIndex,1); //stageIndex为当前页码
          },100);
         }else if (event.keyCode==40) {//绑定40,即向下按钮
           getIndex();
          setTimeout(function(){
            scrollStage(windowobject,stageIndex,-1); //stageIndex为当前页码
          },100);
         }
       });

       //绑定滑轮功能的函数
       function handle(delta){
         getIndex();
        if (delta<0) {
          setTimeout(function(){
            scrollStage(windowobject,stageIndex,-1); //stageIndex为当前页码
          },100);
        }else{
          setTimeout(function(){
            scrollStage(windowobject,stageIndex,1); //stageIndex为当前页码
          },100);
        }

       }

       //判断滑轮,解决兼容性
       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(event) {
         if (e.which==2) {//which=2代表鼠标滚轮,即为中键
           this.stopDefaultAndBubble(e);
           //bugfix 搜狗浏览器的ie内核只有在定时器触发这个函数才生效
           setTimeout(function(){
             this.stopDefaultAndBubble(e);
           },10);
         }
       });

       //如果有ul li控制按钮
       if (objControl!=null) {
         $(objControl).delegate('li', 'click', function() {
           stageIndex=$(this).index();
           setTimeout(function(){
             scrollStage(windowobject,stageIndex,0);
           },100);
         });
       }

       function scrollStage(obj,stIndex,dir){//如果用scrollStage=function来指定的话没有声明提前,然后就会找不到这个函数了
         //obj为操作滚动的对象
        //stIndex为点击调用时应该滚动到的页面页码,按键和滚轮调用时默认为1(传入0)
        //dir传入滚动时的方向,0代表不滚动,1代表向上,-1代表向下
        var sIndex=stIndex;//!(dir)则stageIndex为要到的页码,否则为当前页码
        var windowobject=obj;
        var direction=0||dir; //接收参数封装,没有传入时暂时认为为0
        var target=windowHeight*sIndex; //目标页面距离文档顶部距离
       
        if ( !$(windowobject).is(':animated') ) {//当没有在滚动时
          if(!direction){ ////响应guider,此时stageIndex为目标页面页码
            if ($(window).scrollTop() > target) { //内容下移,窗口上移,上方出现弹痕
              direction=-1;
              $(windowobject).animate({
                "scrollTop": target +"px"
              },1000*speed,function(){
                crash_bottom(1,target,20,150); //调用撞击函数,先撞顶部,target变成当前页面了
              });
            }else if($(window).scrollTop() == windowHeight*sIndex){ //当前页面时
              direction=0;
              crash_bottom(1, target ,20,150); //模拟撞底部
            }else{
              direction=1;
              $(windowobject).animate({
                "scrollTop": target +"px"
              },1000*speed,function(){
                crash(1,target,20,150); //调用撞击函数,先撞底部

              });
            }
          }else{//响应鼠标滚轮和键盘上下,sindex为当前页面
            if(direction==1){
              if(sIndex==0){
                crash(1,target,20,150);
              }else{ //往上翻
                sIndex-=1;
                $(windowobject).animate({
                  "scrollTop":windowHeight*sIndex+"px"
                  },1000*speed,function(){
                    crash_bottom(1,windowHeight*sIndex,20,150); //调用撞击函数,往下翻内容往上,先撞顶部
                  }
                );
              }
            }else{
              if(sIndex==listMax){
                crash_bottom(1,target,20,150);
              }else{ //往下翻
                sIndex+=1;
                $(windowobject).animate({
                  "scrollTop":windowHeight*sIndex+"px"
                },1000*speed,function(){
                  crash(1,windowHeight*sIndex,20,150); //调用撞击函数,往上翻内容往下,先撞底部
                });

              }
            }
          }
        }
       }

      //撞击函数
      function crash_bottom(direction,termin,distant,time){
        if (!stop) {
          var scrollTop=$(window).scrollTop();
          if (direction==1) {
            direction=0;
            $(windowobject).animate({"scrollTop":"+="+distant+"px"},time,function(){
              crash_bottom(direction,termin,distant*0.6,time);
              if (distant<=15||time>150) {
                stop=1;//停止碰撞

                $(windowobject).animate({"scrollTop":termin+"px"},time,function(){
                  stop=0;
                });
              }
            });
          }else if (direction==0) {
            direction=1;
            $(windowobject).animate({"scrollTop":termin+"px"},time,function(){
              crash_bottom(direction,termin,distant*0.6,time);
              if (distant<=15||time>150) {
                stop=1;//停止碰撞

                $(windowobject).animate({"scrollTop":termin+"px"},time,function(){
                  stop=0;
                });
              }
            });
          }
        }
      }
      function crash(direction,termin,distant,time){
        if (!stop) {
          var scrollTop=$(window).scrollTop();
          if (direction==1) {
            direction=0;
            $(windowobject).animate({"scrollTop":"-="+distant+"px"},time,function(){
              crash(direction,termin,distant*0.6,time);
              if (distant<=15||time>150) {
                stop=1;//停止碰撞

                $(windowobject).animate({"scrollTop":termin+"px"},time,function(){
                  stop=0;
                });
              }
            });
          }else if (direction==0) {
            direction=1;
            $(windowobject).animate({"scrollTop":termin+"px"},time,function(){
              crash(direction,termin,distant*0.6,time);
              if (distant<=15||time>150) {
                stop=1;//停止碰撞

                $(windowobject).animate({"scrollTop":termin+"px"},time,function(){
                  stop=0;
                });
              }
            });
          }
        }
      }

     },
     //左右滚动的方法
     horizontalMove:function(){
       var obj=this.$element; //最外层对象
       var speed=this.options.horizontalSpeed;
       var objControl=this.options.objControlUl;//控制按钮

       var windowWidth=$(window).width();
       var list=$(obj).children('.page');
       var listMax=$(list).length;

       var is_chrome=navigator.userAgent.toLowerCase().indexOf('chrome')>-1;
       if(is_chrome){
         //判断webkit内核,供scrollTop兼容性使用
         windowobject='body';
       }else{
         //支持IE和FF
         windowobject='html';
       }
       var stop=0;

       //均设置为windows大小
       this.setSize(obj);
       $(obj).css({'width':windowWidth*listMax+'px'});

       var pageIndex; //当前页面页码(负数)
      function getPageIndex(){
        pageIndex=Math.round(parseInt($(obj).css("margin-left")) / windowWidth);
      }

      //绑定键盘左右按键事件
      $(document).keydown(function(event){
        //判断event.keyCode为39(即向右按钮)
        if (event.keyCode==39) {
          getPageIndex();
          scrollPage($(obj),pageIndex,-1); 
        }
        //判断event.keyCode为37(即向左按钮
        else if (event.keyCode==37) {
          getPageIndex();
          scrollPage($(obj),pageIndex,1);
        }
      });

      //如果有ul li控制按钮
       if (objControl!=null) {
         $(objControl).delegate('li', 'click', function() {
           pageIndex=$(this).index();
           setTimeout(function(){
             scrollPage(obj,pageIndex,0);
           },100);
         });
       }

      function scrollPage(obje,pIndex,dir){
        var windowobject=obje;
        var direction=0||dir;
        var pageIndex=pIndex;
        var dist=Math.round(parseInt($(obj).css("margin-left"))); //当前页距离左边的margin(负值)
        var aim=pageIndex*windowWidth*(-1);

        if (!$(windowobject).is(":animated")) {
          if(!direction){ //响应nav

            if (dist != aim) { //此时pageIndex为yearID.非负值
              $(windowobject).animate({"margin-left": aim + "px"},
                1000*speed);
            }else{
              direction=0;
              $(windowobject).animate({"margin-left":"+="+"50px"},500).animate({"margin-left":"-="+"100px"},500).animate({"margin-left":"+="+"50px"},500);
            }
          }else{ //响应键盘左右键
            if(direction==1){ //pageIndex为负值
              if(pageIndex==0){
                $(windowobject).animate({"margin-left":"+="+"50px"},500).animate({"margin-left":"-="+"100px"},500).animate({"margin-left":"+="+"50px"},500);  
              }else{
                pageIndex+=1; //显示左边内容,左键
                $(windowobject).animate({"margin-left":"+=" + windowWidth + "px"},
                  1000*speed);
              }
            }else{
              if(pageIndex== ((-1)*(listMax-1))){
                $(windowobject).animate({"margin-left":"-="+"50px"},500).animate({"margin-left":"+="+"100px"},500).animate({"margin-left":"-="+"50px"},500);  
              }else{
                pageIndex-=1;
                $(windowobject).animate({"margin-left":"-=" + windowWidth + "px"},
                  1000*speed);
              }
              
              
            }
          }
        }
      }

     }
   }

   //在插件中使用windowObj对象的方法,0为vertical,1为horizontal
   $.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{//2之后的留扩展吧
       //add some functions
     }
   }
 })(jQuery,window,document);

详细的代码下载见https://github.com/codetker/myWindowScroll

以上所述就是本文的全部内容了,希望大家能够喜欢。

Javascript 相关文章推荐
javascript写的一个链表实现代码
Oct 25 Javascript
Jquery实现无刷新DropDownList联动实现代码
Mar 08 Javascript
Jquery 选中表格一列并对表格排序实现原理
Dec 15 Javascript
原生JS实现加入收藏夹的代码
Oct 24 Javascript
Extjs4中Form的使用之本地hiddenfield
Nov 26 Javascript
javascript中文本框中输入法切换的问题
Dec 10 Javascript
JavaScript中通过prototype属性共享属性和方法的技巧实例
Mar 13 Javascript
jQuery on()方法使用技巧详解
Apr 16 Javascript
利用JS实现文字的聚合动画效果
Jan 22 Javascript
js仿QQ邮箱收件人选择与搜索功能
Feb 10 Javascript
微信小程序仿RadioGroup改变样式的处理方案
Jul 13 Javascript
Vue如何循环提取对象数组中的值
Nov 18 Vue.js
jQuery实现模拟marquee标签效果
Jul 14 #Javascript
jQuery插件boxScroll实现图片轮播特效
Jul 14 #Javascript
jQuery自动添加表单项的方法
Jul 13 #Javascript
JavaScript去除数组里重复值的方法
Jul 13 #Javascript
javascript实现根据iphone屏幕方向调用不同样式表的方法
Jul 13 #Javascript
jQuery检测返回值的数据类型
Jul 13 #Javascript
jQuery常用且重要方法汇总
Jul 13 #Javascript
You might like
让CodeIgniter的ellipsize()支持中文截断的方法
2014/06/12 PHP
php实现简单文件下载的方法
2015/01/30 PHP
人脸识别测颜值、测脸龄、测相似度微信接口
2016/04/07 PHP
php生成与读取excel文件
2016/10/14 PHP
createElement与createDocumentFragment的点点区别小结
2011/12/19 Javascript
使用js实现按钮控制文本框加1减1应用于小时+分钟
2013/12/09 Javascript
js验证IP及子网掩码的合法性有效性示例
2014/04/30 Javascript
jquery+php实现搜索框自动提示
2014/11/28 Javascript
node.js中的console.trace方法使用说明
2014/12/09 Javascript
node.js中的fs.writeFile方法使用说明
2014/12/14 Javascript
javascript常用方法总结
2015/05/14 Javascript
JS实现的简洁纵向滑动菜单(滑动门)效果
2015/10/19 Javascript
jQuery+json实现的简易Ajax调用实例
2015/12/14 Javascript
jquery实现删除一个元素后面的所有元素功能
2015/12/21 Javascript
Javascript将JSON日期格式化
2016/08/23 Javascript
微信JS SDK接入的几点注意事项(必看篇)
2017/06/23 Javascript
Angular 4根据组件名称动态创建出组件的方法教程
2017/11/01 Javascript
Angular6封装http请求的步骤详解
2018/08/13 Javascript
vue基础之使用get、post、jsonp实现交互功能示例
2019/03/12 Javascript
vue中echarts引入中国地图的案例
2020/07/28 Javascript
[46:00]DOTA2上海特级锦标赛主赛事日 - 2 胜者组第一轮#4EG VS Fnatic第一局
2016/03/03 DOTA
[59:53]DOTA2-DPC中国联赛 正赛 VG vs Elephant BO3 第二场 3月6日
2021/03/11 DOTA
python多线程抓取天涯帖子内容示例
2014/04/03 Python
Python编写屏幕截图程序方法
2015/02/18 Python
Python实现定时精度可调节的定时器
2018/04/15 Python
Python数据处理篇之Sympy系列(五)---解方程
2019/10/12 Python
Django调用支付宝接口代码实例详解
2020/04/04 Python
使用python无账号无限制获取企查查信息的实例代码
2020/04/17 Python
手把手教你如何用Pycharm2020.1.1配置远程连接的详细步骤
2020/08/07 Python
经贸韩语专业大学生职业规划
2014/02/14 职场文书
网络优化专员求职信
2014/05/04 职场文书
医院搬迁方案
2014/06/14 职场文书
2019年大学生职业生涯规划书最新范文
2019/03/25 职场文书
MySQL子查询中order by不生效问题的解决方法
2021/08/02 MySQL
Windows 11上手初体验:任务栏和开始菜单等迎来大改
2021/11/21 数码科技
正则表达式拆分url实例代码
2022/02/24 Java/Android