zoukankan      html  css  js  c++  java
  • 用JQ仿造百度书籍预售页面的单屏滚页效果

    今天的项目需要做到一个介绍页面,我主动提出走单屏滚页的风格,毕竟交互性好,逼格也高,具体效果可以参照百度知道书籍预售页面

    其实现效果就大概是这样的:

    还是老样子,所有步骤文件可以从我的Github上下载。

    原理

    滚页的方式肯定是通过animate来实现,由被点击的a标签索引来确定要从哪一页滚至哪一页的位置。同时也需要一个全局变量来存储当前页面的索引,这样方便我们通过鼠标滚轮事件来滚页。

    另外这里也调用了回调事件,包括点击时被激活页面的回调,以及其它非激活页面的回调,为了提高复用我们会动用 eval() 来帮忙,不过注意这两个回调都应该是在滚页(animate)之后触发的。

    我们先写下页面原型:

    <!DOCTYPE html>
    <html>
      <head>
        <meta http-equiv="Content-type" content="text/html; charset=utf-8">
        <title>滚页效果</title>
        <script src="jq.js"></script>
        <style type="text/css">
          body,html {height:100%; margin:0;}
          .screen_wrap{position:relative; height:100%; overflow:hidden;}
          .page{ position:relative; padding:20px;width:100%; height:100%;}
          .page0{ background:yellow;}
          .page1{ background:red;color:white;}
          .page2{ background:green;}
          .page3{ background:blue;color:yellow;}
          .page4{ background:gray; color:white;}
          .bottom_nav{ position:fixed; bottom:0px;padding:10px 0px;width:100%; text-align:center; background:black; opacity:0.8;}
          .bottom_nav a{margin:0px 10px; color:white;}
        </style>
        <script type="text/javascript">
        $(function(){
            
        })
        </script>
      </head>
      <body>
            <div class="screen_wrap" id="screen_wrap">
                <div class="page page0">第一页</div>
                <div class="page page1">第二页</div>
                <div class="page page2">第三页</div>
                <div class="page page3">第四页</div>
                <div class="page page4">第五页</div>
            </div>
            <div class="bottom_nav" id="bottom_nav">
            <a href="#!/1">第1页</a>
            <a href="#!/2">第2页</a>
            <a href="#!/3">第3页</a>
            <a href="#!/4">第4页</a>
            <a href="#!/5">第5页</a>
            </div>
      </body>
    </html>

    注意必须设置body,html高度为100%,否则无法设置单页的高度(原理可以戳这里

    接着写脚本,要让这几个page能够在后续上下运动起来,我们得给它包裹一层div。

    $(function(){
        var $a = $("#bottom_nav a");
        var $wrap = $("#screen_wrap");
        var $pages = $wrap.children();
        var $moveWrap = $("<div></div>");
        $moveWrap.css({"position":"relative","height":"100%"});
        $pages.wrapAll($moveWrap); //给五个page外面再包上一层div用以后续上下运动
    })

    有的朋友可能会好奇,现在不是已经有一层 id="screen_wrap" 的div围住它们了么,为何还要再裹一层。这是因为screen_wrap主要是满足我们“单屏”的需求,即通过设置100%的高度以及 overflow:hidden 来防止浏览器出现滚动条。

    另外我们要考虑到,如果窗口发生了缩放,那么page们运动的幅度就不能按照原先的幅度了,我们得重新给幅度做定义(幅度以当前窗口高度为单位):

    $(function(){
        var a_index=0,thetop,win_h;
        var $a = $("#bottom_nav a");
        var $wrap = $("#screen_wrap");
        var $pages = $wrap.children();
        var $moveWrap = $("<div></div>");
        $moveWrap.css({"position":"relative","height":"100%"});
        $pages.wrapAll($moveWrap);
        var getHeight = function(){ //获取当前窗口高度
            win_h = $.VJ_getWin().h;
            $a.eq(a_index).click(); //防止窗口缩放时页面布局混乱
        }
        getHeight();
        $(window).on("resize",getHeight); //窗口缩放时,重新初始化上行运动的幅度
    })

    进一步定义点击a标签的触发事件,让page滚动起来:

    $(function(){
        var a_index=0,thetop,win_h;
        var $a = $("#bottom_nav a");
        var $wrap = $("#screen_wrap");
        var $pages = $wrap.children();
        var $moveWrap = $("<div></div>");
        $moveWrap.css({"position":"relative","height":"100%"});
        $pages.wrapAll($moveWrap);
        var getHeight = function(){
            win_h = $(window).height();
            $a.eq(a_index).click();
          }
        getHeight();
        $(window).on("resize",getHeight);
        $a.click(function(){
            a_index = $a.index(this);
            thetop = a_index * win_h;  //注意之前说的“上下运动的幅度”指的就是这个,主要依赖当前窗口高度
            $pages.parent().animate({"top":-thetop},500);
        })
    })

    接着添加回调事件,先添加激活页面的回调:

    $(function(){
        var a_index=0,thetop,win_h;
        var $a = $("#bottom_nav a");
        var $wrap = $("#screen_wrap");
        var $pages = $wrap.children();
        var $moveWrap = $("<div></div>");
        $moveWrap.css({"position":"relative","height":"100%"});
        $pages.wrapAll($moveWrap);
        var getHeight = function(){
            win_h = $(window).height();
            $a.eq(a_index).click();
          }
        getHeight();
        $(window).on("resize",getHeight);
        $a.click(function(){
            a_index = $a.index(this);
            thetop = a_index * win_h; 
            $pages.parent().stop().animate({"top":-thetop},500,  //加个.stop() 防止卡顿
                function(){  //animate结束后的回调
                    var hasfun = eval("typeof page"+a_index+"==='function'");
                    if(hasfun){
                        eval("page"+a_index+"()");  //如果有回调函数则执行该函数
                    }
                }
            );
        })
        var page1 = function(){ //激活页面的回调
            $(".page1").animate({"opacity":"0.2"},2000);
        }
        var page3 = function(){
            $(".page3").animate({"opacity":"0.5"},4000);
        }
    })

    这里动用了 eval() 来帮忙,关键时刻还是蛮好用的,虽然常规还是建议少用eval方法。

    我们继续添加非激活页面的回调/初始化事件(就是比如你点了page2,切页后page0-1、page3-4要回调的事件):

    $(function(){
      var a_index=0,thetop,win_h,hasfun;
      var $a = $("#bottom_nav a");
      var a_len = $a.length;  //获得a的个数(其实也就是page个数)
      var $wrap = $("#screen_wrap");
      var $pages = $wrap.children();
      var $moveWrap = $("<div></div>");
      $moveWrap.css({"position":"relative","height":"100%"});
      $pages.wrapAll($moveWrap);
      var getHeight = function(){
          win_h = $(window).height();
          $a.eq(a_index).click();
        }
      getHeight();
      $(window).on("resize",getHeight);
      $a.click(function(){
          a_index = $a.index(this);
          thetop = a_index * win_h; 
          $pages.parent().stop().animate({"top":-thetop},500,
              function(){  //animate结束后的回调
                  hasfun = eval("typeof page"+a_index+"==='function'");
                  if(hasfun){
                      eval("page"+a_index+"()");  //如果有回调函数则执行该函数
                  } 
                  for(var i=0;i<a_len;i++){ 
                      if(i==a_index) continue;
                      hasfun = eval("typeof reset"+i+"==='function'"); 
                      if(hasfun){ 
                      eval("reset"+i+"()");  //如果有其它page初始化函数则执行该函数
                      }
                  }
              }
          );
      })
      var page1 = function(){
          $(".page1").animate({"opacity":"0.2"},2000);
      }
      var page3 = function(){
          $(".page3").animate({"opacity":"0.5"},4000);
      }
      var reset1 = function(){ //初始化函数
          $(".page1").stop().css({"opacity":"1"});
      }
      var reset3 = function(){
          $(".page3").stop().css({"opacity":"1"});
      }
    })

    至此,我们要的效果就基本完成了(除了监听鼠标滚轮事件),我们贴下完整代码:

    <!DOCTYPE html>
    <html>
      <head>
        <meta http-equiv="Content-type" content="text/html; charset=utf-8">
        <title>滚页效果</title>
        <script src="jq.js"></script>
        <style type="text/css">
          body,html {height:100%; margin:0;}
          .screen_wrap{position:relative; height:100%; overflow:hidden;}
          .page{ position:relative; width:100%; height:100%;}
          .page0{ background:yellow;}
          .page1{ background:red;color:white;}
          .page2{ background:green;}
          .page3{ background:blue;color:yellow;}
          .page4{ background:gray; color:white;}
          .bottom_nav{ position:fixed; bottom:0px;padding:10px 0px;width:100%; text-align:center; background:black; opacity:0.8;}
          .bottom_nav a{margin:0px 10px; color:white;}
        </style>
        <script type="text/javascript">
    $(function(){
      var a_index=0,thetop,win_h,hasfun;
      var $a = $("#bottom_nav a");
      var a_len = $a.length;  //获得a的个数(其实也就是page个数)
      var $wrap = $("#screen_wrap");
      var $pages = $wrap.children();
      var $moveWrap = $("<div></div>");
      $moveWrap.css({"position":"relative","height":"100%"});
      $pages.wrapAll($moveWrap);
      var getHeight = function(){
          win_h = $(window).height();
          $a.eq(a_index).click();
        }
      getHeight();
      $(window).on("resize",getHeight);
      $a.click(function(){
          a_index = $a.index(this);
          thetop = a_index * win_h; 
          $pages.parent().stop().animate({"top":-thetop},500,
              function(){  //animate结束后的回调
                  hasfun = eval("typeof page"+a_index+"==='function'");
                  if(hasfun){
                      eval("page"+a_index+"()");  //如果有回调函数则执行该函数
                  } 
                  for(var i=0;i<a_len;i++){ 
                      if(i==a_index) continue;
                      hasfun = eval("typeof reset"+i+"==='function'"); 
                      if(hasfun){ 
                      eval("reset"+i+"()");  //如果有其它page初始化函数则执行该函数
                      }
                  }
              }
          );
      })
      var page1 = function(){
          $(".page1").animate({"opacity":"0.2"},2000);
      }
      var page3 = function(){
          $(".page3").animate({"opacity":"0.5"},4000);
      }
      var reset1 = function(){ //初始化函数
          $(".page1").stop().css({"opacity":"1"});
      }
      var reset3 = function(){
          $(".page3").stop().css({"opacity":"1"});
      }
    })
        </script>
      </head>
      <body>
            <div class="screen_wrap" id="screen_wrap">
                <div class="page page0">第一页</div>
                <div class="page page1">第二页</div>
                <div class="page page2">第三页</div>
                <div class="page page3">第四页</div>
                <div class="page page4">第五页</div>
            </div>
            <div class="bottom_nav" id="bottom_nav">
            <a href="#!/1">第1页</a>
            <a href="#!/2">第2页</a>
            <a href="#!/3">第3页</a>
            <a href="#!/4">第4页</a>
            <a href="#!/5">第5页</a>
            </div>
      </body>
    </html>
    View Code

    后续大家可以自行加上鼠标滚轮事件,向上和向下分别触发上滚页和下滚页事件,由于监听鼠标滚轮事件又是一门小学问,在这里就不赘述了。

    但你可以通过这里来获得包括鼠标滚轮事件在内的全部效果,我把单屏滚页事件和鼠标滚轮监听事件都封装到我的个人插件VaJoyJS中,有兴趣的朋友可以从我插件源码中一窥究竟。

    共勉~

  • 相关阅读:
    Android开发之旅1:环境搭建及HelloWorld
    程序员学习视频教程汇总
    Maven项目下update maven后Eclipse报错:java.lang.ClassNotFoundException: ContextLoaderL
    查看控制层从前端传来的参数
    PostMethod和GetMethod用法
    @Transient的用法和格式化页面展示的数据格式
    修改hosts
    javascript:history.go(-1)的使用
    JsonConfig的jsonConfig.setExcludes的用法
    验证登录超时,在登录后跳转超时时的页面
  • 原文地址:https://www.cnblogs.com/vajoy/p/3991770.html
Copyright © 2011-2022 走看看