封装自己的jq myFullPage插件

封装自己的jq myFullpage插件

  • 首先了解fullPage的工作原理 在这里插入图片描述
    可以鼠标键盘监听事件和鼠标滚轮来控制屏幕滚动的那种效果
    在这里插入图片描述
    类似于这样的布局方式,创建class类名box容器,然后在容器里面根据需求生成三个section页面,在根据需求在section页面里面生成silde横屏滚动,在创建一个WapperSilde容器将silde页面包裹起来插入在section当中

jq方式引入fullpage插件

  • 重要参数,监测页数滚动完成和过程中
    • onLeave :页面离开后触发,index显示当前页数
    • afterLoad :离开后到达当前页面触发,index显示页数,两个参数,第二个参数是页数
    //示例
     $("#wapper").fullpage({
              afterLoad : function (a,index){
                  console.log("后",index)
              },
              onLeave : function (index){
                  console.log("先",index)
              }
          })
    

    封装自己的myFullPgae

需要填写的参数和值,自定义

  • 将自己要生成的classbox类名加工进方法里
pageEngine.init(".box",["red" ,"yellow", "green"])
 .addSection("oneSection1")//生成第一个section
 	//第一个页面的样式,这里就不复制粘贴了基本上每一个样式都是一样的
 	 .addComponent({
        className: "jiuyi",
        type: 'base', //根据该属性来生成不一样的效果
        width: 100,
        height: 100,
        text: "这里是九依的fullpage demo11",
        center: true,
        css: {
            position: "absolute",
            opacity: 0,
            top: 0,
            backgroundImage: "url(./src/images/6.jpg)",
            backgroundSize: "100% 100%",
            padding: "10px 15px 10px 15px",
            textAlign: "justify",
            fontSize: "18px",
            fontWeight: "900",
            lineHeight: "25px",
        },
        event : {
         click : function (){
         
         },
         mouseover : function(){
         
         }
        },
        //下两个控制入场离场动画
        animateIn: {
            opacity: 1,
            top: 240,
        },
        animateOut: {
            opacity: 0,
            top: 0,
        },
        delay:500 //延迟时间
    })
 .addSection("oneSection2")//生成第二个section
 	 .addSilde("2-1 silde")//生成第二个section的第一个silde
 	 .addSilde("2-2 silde")//生成第二个section的第二个silde
 	 .addSilde("2-3 silde")//生成第二个section的第三个silde
 .addSection("oneSection3")//生成第三个section
 //启动
 .load()

封装pageEngine方法 - 容器生成

//开始生成,启动函数,初始化值
var pageEngine = {
		//准备工作
	init: function (selector, colorsArray) {
       this.$W = $(selector); //将传进来的值jq包装
       this.colorsArray = colorsArray; //第二个参数,颜色
       this.sildeFlag = false; //判断是section,还是silde
   	   return this; //链式调用的精髓,将当前方法返回回去,该对象全局都可以用
    },
    //生成section页面	 class自定义类名
     addSection: function (className) {
        this.sildeFlag = false; 	//这是生成类名             用户自定义类名
        this.$Pgae = $("<div class = ' section' />").addClass(className);
        this.$Pgae.appendTo(this.$W) //将该secition塞入进box容器里面
        return this; 
    },
    //生成silde页面
     addSilde: function (className) {
        this.sildeFlag = true;
        this.$silde = $("<div class = 'silde' />").addClass(className);
        this.$silde.appendTo(this.$Pgae) //this指向pageEngine
        return this;
    },
    //将创建出来的页面设置用户传入的Css值,留接口
     addComponent: function (config) {
        var oCp = null;
        switch (config.type) { 	//根据type,来生成不一样的效果
            case "base": {
                oCp = ComponentFactory(config); //设置css值的方法
                break;
            }
        }
        //如果sildeFlag是ture,就把oCp加入在silde里面,如果是false就加入在section里
        this.sildeFlag ? this.$silde.append(oCp) : this.$Pgae.append(oCp);
        return this;
    },
}

ComponentFactory方法

var ComponentFactory = function (config) {
   var $Div = $('<div class="component base"</div>'); //生成展示类容
   //用户自定义属性
   config.className && $Div.addClass(config.className); 
   config.width && $Div.css("width", config.width);
   config.height && $Div.css("height", config.height);
   config.text && $Div.text(config.text);
   config.center && $Div.css({ position: "absolute", left: "50%", marginLeft: -config.width / 2 });
   config.css && $Div.css(config.css);
    //事件处理
    if (config.event) {
      for (var prop in config.event) {
          $Div.on(prop, config.event[prop]);
       }
    }
	//自定义事件,动画
   $Div.on("cpLeave", function () {
      var self = this; //当前展示效果盒子记录
      setTimeout(function () {
      		//用户自定义动画移出效果
         config.animateOut && $(self).animate(config.animateOut)
         //延迟时间
      }, config.delay);
   });
   $Div.on("cpLoad", function () {
      var self = this;
      setTimeout(function () {
      //用户自定义动画移入效果
         config.animateIn && $(self).animate(config.animateIn)
      }, config.delay);
   });
   return $Div; //这个时候oCp拿着这个闭包的,展示效果
}

接着上面的继续来

var pageEngine = {
		//准备工作
	init: function (selector, colorsArray) {
       this.$W = $(selector); //将传进来的值jq包装
       this.colorsArray = colorsArray; //第二个参数,颜色
       this.sildeFlag = false; //判断是section,还是silde
   	   return this; //链式调用的精髓,将当前方法返回回去,该对象全局都可以用
    },
    //生成section页面	 class自定义类名
     addSection: function (className) {
        this.sildeFlag = false; 	//这是生成类名             用户自定义类名
        this.$Pgae = $("<div class = ' section' />").addClass(className);
        this.$Pgae.appendTo(this.$W) //将该secition塞入进box容器里面
        return this; 
    },
    //生成silde页面
     addSilde: function (className) {
        this.sildeFlag = true;
        this.$silde = $("<div class = 'silde' />").addClass(className);
        this.$silde.appendTo(this.$Pgae) //this指向pageEngine
        return this;
    },
    //将创建出来的页面设置用户传入的Css值,留接口
     addComponent: function (config) {
        var oCp = null;
        switch (config.type) { 	//根据type,来生成不一样的效果
            case "base": {
                oCp = ComponentFactory(config); //设置css值的方法
                break;
            }
        }
        //如果sildeFlag是ture,就把oCp加入在silde里面,如果是false就加入在section里
        this.sildeFlag ? this.$silde.append(oCp) : this.$Pgae.append(oCp);
        return this;
    },
     bindEvent: function () {
     
        this.$W.find(".section").on({
        //这是控制里面的动画,就是控制翻页之后的移入移出动画,是ComponentFactory方法里面的
            _leave: function () {
            //移出
                $(this).find(".component").trigger("cpLeave")
            },
            _load: function () {
            //移入
            //$(this).find(".component")就是oCp生成的那个容器,让他做出相应动画
                $(this).find(".component").trigger("cpLoad")
            }
        })
    },
    //启动函数
     load: function () {
     	//生成完所有容器启动该方法
        var self = this;
        this.bindEvent();
		//主角fullPage方法
        this.$W.myFullpage({
            colorsArray: this.colorsArray,
            onLeave: function (index) {
                self.$W.find(".section").eq(index).trigger("_leave");
            },
            afterLoad: function (index) {
                self.$W.find(".section").eq(index).trigger("_load");
            }
        });
        //初始话第一个section加入移出移入动画效果
    this.$W.find(".section").eq(0).trigger("_load");
    }
}

封装自己的myFullPage

  • 首先先在jq工具方法里面加入自己的方法名称,config用于接收传递参数
$.fn.extend({
  	 myFullpage: function (config) {
  	 
  	 }
})

初始化值,准备工作


  $.fn.extend({
  	 myFullpage: function (config) {
  	  var colorArray = config.colorsArray; //页面颜色,用于开发
      var $W = $(this); //将传递的box,先用jq包裹起来后面用得到
      var $Section = $W.find(".section") //生成的section子页
      // 初始化值
      var chuShiHhua = { //整屏高度宽度初始化占满整屏
          width: "100%",
          height: "100%"
      }
      //获取当前窗口的高度宽度
      var clientWidth = window.innerWidth;
      var clientHeight = window.innerHeight;
      
      var curindex = 0; //后续参数,用于计数,页数,看向上向下移动的时候的参数
      var key = true;	// 防止用户键盘按的过快出现的bug
      var curindexLeft = 0; //记录水平方向页数
  	 }
})

初始化CSS和生成容器


// 让因为要让Html整屏滚动,所以就在这里设置的外边距,溢出部分隐藏
  $("html")
          .css({
              margin: "0px",
              overflow: "hidden",
              position: "relative"
          })
          //集中操作
          .add("body")
          .add($W)
          .add($Section)
          .css(chuShiHhua)
      $W
          .css({
              position: "absolute",
              left: "0px",
              top: "0px"
          })
          //选中section对每一个页面添加颜色,方便开发
          .find($Section).each(function (index, ele) {
              $(ele) 
                  .css({ backgroundColor: colorArray[index], position: "relative" })
                  //如果下面有silde的话就让她的宽高等于整个屏幕宽度并且浮动
                  .find(".silde")
                  .css({ width: clientWidth, height: clientHeight, float: "left", position: "relative" })
                  //再给silde创建一个className为WapperSIlde的父容器
                  .wrapAll("<div class ='WapperSilde'></div>")
          })
          //对WapperSilde进行样式操作
            $Section.find(".WapperSilde")
          .css({ position: "absolute", left: "0px", top: "0px" })
          .each(function (index, ele) {
              $(ele)
                  .css({
                      width: $(ele)
                          .find(".silde")
                          //整体宽度的关于他的儿子容器 * 屏幕宽度
                          .size() * innerWidth, height: innerHeight
                  })
          })

  //运动,页面运动+active激活状态
   $Section.eq(0)
   		//给第一个section一个active类名
          .addClass("active")
          //回退操作
          .end()
          .find(".WapperSilde")
          //给每一个WapperSilde下面的silde添加一个inneractive类名
          .each(function (index, ele) {
              $(ele).
                  find(".silde")
                  .eq(0)
                  .addClass("inneractive")
          })
     // 鼠标滚轮判断事件
     //		全局鼠标判断								防抖
//我这里直接将防抖放进来,以供参考
function debounce(handler, delay) {
  var timer = null;
  return function () {
      var _self = this, _arg = arguments;
      //先清除上一个定时器
      clearTimeout(timer);
      timer = setTimeout(function () {
      	//当前handler的this指向为document
          handler.apply(_self, _arg);
          //延迟时间
      }, 500)
  }
}

      $(document).on("mousewheel DOMMouseScroll", debounce(function (event) {
      //获取当前整屏高度
          var newtop = $W.offset().top;
          //局部变量,检测鼠标向上滚动或者向下滚动,预留接口,保留向上向下移动的值
  	    var dicrction = "";
          var dicrction = (event.originalEvent.wheelDelta && (event.originalEvent.wheelDelta > 0 ? 1 : -1)) || (event.originalEvent.detail && (event.originalEvent.detail > 0 ? -1 : 1));
          								//向上移动越界判断
          if(dicrction == 1 && curindex != 0){
          /向上移动
              dicrction = "top";
              //当前的位置,向上
              config.onLeave(curindex, dicrction)
              curindex--;
              //让newtop加等于clientHeight高的位置
              newtop += clientHeight;
              
              //向下移动
          }else if(dicrction == -1 && curindex != $Section.size() - 1){
              dicrction = "bottom";
              config.onLeave(curindex, dicrction)
              curindex++;
              newtop -= clientHeight;
          }
          //动画效果
          //全局匀速运动,
          $W.animate({ top: newtop }, 500, "swing", function () {
          	//锁,防止在运动之后有其他操作出现的bug
              key = true;
              //给section当前的页数加上acrive激活效果
              $Section.eq(curindex).addClass("active");
              	//dirction的作用来了,如果是向上,让之前的那个acrive消除
              if (dicrction == "top") {
              				//如果是向上,那就当前位置的上一个,就是+1的索引位置去掉active
                  $Section.eq(curindex + 1).removeClass("active");
              } else {
           //如果是向下,那就当前位置的上一个,就是-1的索引位去掉active
                  $Section.eq(curindex - 1).removeClass("active")
              }
              //移动之后触发的当前页面的索引位和方向
              config.afterLoad(curindex, dicrction)
          })
      
      }, 1500));

// 键盘事件
      $(document).on("keydown", function (e) {
          //判断垂直方向,和鼠标滚动事件一模一样
     	     if (e.which == 38 || e.which == 40) {
              if (key) {
                  key = false;
                  var newtop = $W.offset().top;
                  var dicrction = "";
                  if (e.which == 38 && curindex != 0) {
                      dicrction = "top";
                      config.onLeave(curindex, dicrction)
                      curindex--;
                      newtop += clientHeight;

                  } else if (e.which == 40 && curindex != $Section.size() - 1) {
                      dicrction = "bottom";
                      config.onLeave(curindex, dicrction)
                      curindex++;
                      newtop -= clientHeight;
                  }
                  $W.animate({ top: newtop }, 500, "swing", function () {
                      key = true;
                      $Section.eq(curindex).addClass("active");
                      if (dicrction == "top") {
                          $Section.eq(curindex + 1).removeClass("active");
                      } else {
                          $Section.eq(curindex - 1).removeClass("active")
                      }
                      config.afterLoad(curindex, dicrction)
                  })
              }
          }
  //判断水平方向的键盘事件
  		//越界兼容,如果左右方向没有页面的话,则是没办法使用该事件的,如果有自动生成的WapperSilde的类名则可以使用该方法
          if ($($Section[curindex]).find(".WapperSilde").hasClass("WapperSilde")) {
          // 判断左右方向的键
              if (e.which == 37 || e.which == 39) {
                  if (key) {
                      key = false;
                 		// $S用于记住WapperSilde值,方便后续使用
                      var $S = $(".active").find(".WapperSilde");
                      //记录WapperSilde下面的容器方便后续使用
                      var curShowDom = $S.find(".inneractive");
                      //获取当前WapperSilde的定位左边距离
                      var newleft = $S.offset().left;
                      var dicrction = null;
                      //左键盘事件判定
                      					//防止越界,curShowDom.index() 等于0的时候就不能再按左键盘触发事件了
                      if (e.which == 37 && curShowDom.index() != 0) {
                          newleft += clientWidth;
                          dicrction = "left";
                          //参数(计数索引,哪方向移动的)
                          config.onLeave(curindexLeft, dicrction);
                          curindexLeft--;
                          //防止越界,curShowDom.index() 等于0的时候就不能再按右键盘触发事件
                      } else if (e.which == 39 && curShowDom.index() != $S.find('.silde').size() - 1) {
                          newleft -= clientWidth;
                          dicrction = "right";
                            //参数(计数索引,哪方向移动的)
                          config.onLeave(curindexLeft, dicrction);
                          curindexLeft++;
                      }

  					//动画和加inneractive激活方法
                      $S.animate({ left: newleft }, 500, "swing", function () {
                          key = true;
                          // dicrction 如果移动了,就必定会等于left或者right,如果dicrtion等于null就返回""说明没有进入事件,如果能与null,就清除掉curShowDom的所有inneractive
                          dicrction != null ? curShowDom.removeClass('inneractive') : " ";
                          //如果dicrction等于left就是按的左按钮
                          if (dicrction == "left") {
                          //他的左边的,就是上一个兄弟添加inneractive
                              curShowDom.prev().addClass("inneractive")
                              //如果是右按钮
                          } else if (dicrction == "right") {
                          //他的右边的,下一个兄弟添加inneractive
                              curShowDom.next().addClass("inneractive")
                          }
                          //动画完成后,执行的回调函数,参数(当前索引位,方向)
                          config.afterLoad(curShowDom.index(), dicrction)
                      })
                  }
              }
          }
      })
总结

是看的老师的课程边写边练的,基本上大体的运行原理都理解了,不过要自己什么都不翻阅手写一个fullpage还是蛮困难的,在老师原有的基础上,添加了防抖,添加了鼠标滚轮事件,对键盘左右按键的报错进行了兼容,对左右翻页的索引位进行了 调整
目前未解决的bug,左右翻页的时候会出现oCp的运动动画多次调用,导致容器已经显示了还要再执行一遍 animateOut和animateIn,有大佬知道怎么解决吗,不过上下页目前测试还是没什么Bug的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值