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 学习初步 入门教程
Mar 25 Javascript
jQuery实现点击标题输入详细信息
Apr 16 Javascript
IE下window.onresize 多次调用与死循环bug处理方法介绍
Nov 12 Javascript
含有CKEditor的表单如何提交
Jan 09 Javascript
jQuery移除tr无效的解决方法(tr是动态添加)
Sep 22 Javascript
学习JavaScript正则表达式
Nov 13 Javascript
js实现省份下拉菜单效果
Feb 15 Javascript
JS实现的tab切换选项卡效果示例
Feb 28 Javascript
Vue中封装input组件的实例详解
Oct 17 Javascript
JavaScript使用面向对象实现的拖拽功能详解
Jun 12 Javascript
javascript定时器的简单应用示例【控制方块移动】
Jun 17 Javascript
vue移动端使用appClound拉起支付宝支付的实现方法
Nov 21 Javascript
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
Can't create/write to file 'C:\WINDOWS\TEMP\...MYSQL报错解决方法
2011/06/30 PHP
PHP通过插入mysql数据来实现多机互锁实例
2014/11/05 PHP
PHP实现的蚂蚁爬杆路径算法代码
2015/12/03 PHP
phpmyadmin下载、安装、配置教程
2017/05/16 PHP
javascript实现动态增加删除表格行(兼容IE/FF)
2007/04/02 Javascript
自己的js工具_Form 封装
2009/08/21 Javascript
基于jquery的放大镜效果
2012/05/30 Javascript
各种常用的JS函数整理
2013/10/25 Javascript
jQuery setTimeout传递字符串参数报错的解决方法
2014/06/09 Javascript
jQuery显示和隐藏 常用的状态判断方法
2015/01/29 Javascript
jQuery遮罩层实现方法实例详解(附遮罩层插件)
2015/12/08 Javascript
基于jquery编写分页插件
2016/03/07 Javascript
Bootstrap安装环境配置教程分享
2016/05/27 Javascript
jQuery在ie6下无法设置select选中的解决方法详解
2016/09/20 Javascript
微信小程序 表单Form实例详解(附源码)
2016/12/22 Javascript
Vue2 使用 Echarts 创建图表实例代码
2017/05/18 Javascript
基于Two.js实现星球环绕动画效果的示例
2017/11/06 Javascript
node 命令方式启动修改端口的方法
2018/05/12 Javascript
vue路由--网站导航功能详解
2019/03/29 Javascript
ES5 模拟 ES6 的 Symbol 实现私有成员功能示例
2020/05/06 Javascript
通过JS判断网页是否为手机打开
2020/10/28 Javascript
对比Python中__getattr__和 __getattribute__获取属性的用法
2016/06/21 Python
python中实现精确的浮点数运算详解
2017/11/02 Python
python脚本作为Windows服务启动代码详解
2018/02/11 Python
python3安装pip3(install pip3 for python 3.x)
2018/04/03 Python
基于Python实现视频的人脸融合功能
2020/06/12 Python
Python中zipfile压缩文件模块的基本使用教程
2020/06/14 Python
pip已经安装好第三方库但pycharm中import时还是标红的解决方案
2020/10/09 Python
李维斯牛仔裤英国官方网站:Levi’s英国
2019/10/10 全球购物
打架检讨书800字
2014/01/10 职场文书
酒吧创业计划书
2014/01/18 职场文书
服务承诺书范文
2014/05/19 职场文书
开学典礼观后感
2015/06/15 职场文书
Spring Boot优化后启动速度快到飞起技巧示例
2022/07/23 Java/Android
SQLyog的下载、安装、破解、配置教程(MySQL可视化工具安装)
2022/09/23 MySQL
Redis配置外网可访问(redis远程连接不上)的方法
2022/12/24 Redis