欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

jQuery返回定位插件详解

程序员文章站 2023-10-31 21:08:52
一、jquery 提供开发者开发插件的几种模式 1.$.extend();     //这个方法是绑定在$上面的。可以通过$直接调...

一、jquery 提供开发者开发插件的几种模式

1.$.extend();     //这个方法是绑定在$上面的。可以通过$直接调用

2.$.fn.方法名     //这个方法是绑定在dom对象上面的可以通过$('').方法名();调用

3.$.widget   //通过jquery ui 部件工厂模式创建。

二、插件的开发过程

1.$.extend();

这个方法其实很简单,只是像$上面添加了一个静态的方法而已。主要用途是对插件api的扩展.

eg:

//$.extend();为了防止,变量和方法之间的相互污染,我们采用闭包的模式。
  (function($,factory){
    var obj = factory();
    $.extend({
      sayhelloworld:obj.firstapply,
    })
    $.secondapply = obj.secondapply;
  })(jquery,function(){
    var obj = {
      firstapply(){
        console.log('hello world');
      },
      secondapply(){
        console.log('直接绑定到$上');
      },
    };
     return obj;
  });
  $.sayhelloworld();//hello world
  $.secondapply(); //直接绑定到$上
   /*从上面的2种绑定方式可以看出用$.extend();对jquery方法进行拓展,
   其实和直接绑定到$上是一样的效果*/

2.$.fn.方法名。   (方法名 其实就是插件名)。

a.插件结构

<div id="app">app</div>
//$.fn.插件名字 (logtext);
  (function($,factory){

    $.fn.logtext = factory();
  })(jquery,function(){
    var logtext = function(){
      console.log(this.text());
      return this;
    }
    return logtext;
  });
  $("#app").logtext(); //app  通过dom元素之间调用该方法。并返回该对象。这也是jquery实现链式操作的技巧。
  var h = $("#app").logtext().height(); // app
  console.log(h); //18
 //这样就可以自定义方法了。

在jquery插件的开发过程中,其实主要是通过第二种模式($.fn.插件名)开发的。因为jquery的强大之处就是对dom的操作.

b.一个插件的强大之处就是参提供周全的参数。以及方便使用者对参数进行扩展。

<div id="app">app</div>
   //$.fn.插件名字 (mypuglin);
  (function(global,$,factory){
    var common = factory(); //封装插件使用到的函数。
    $.fn.mypuglin = function(opts){  //插件的名称
      var defaults = {}; //默认的api
      opts = $.extend(defaults,opts || {}); //对api的拓展
      /*
       *
       * 要执行的功能
       * 
       */
      console.log(opts.hello);

      return this;
    }
  })(window,jquery,function(){
    var common = {
      a(opt){
        return opt;
      },
    };
    return common;
  });
  $("#app").mypuglin({hello:'hello world'}); //hello world

准备工作已经完毕。那么下面会一个插件为列子,来讲解

3.工作中经常用到的列表到详情。返回来需要保留该位置的插件。(返回定位) savepositon();  $.fn.saveposition

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
  <title>title</title>
  <style>
    @media screen and (max-width: 319px) {
      html {
        font-size: 85.33333px; } }
    @media screen and (min-width: 320px) and (max-width: 359px) {
      html {
        font-size: 85.33333px; } }
    @media screen and (min-width: 360px) and (max-width: 374px) {
      html {
        font-size: 96px; } }
    @media screen and (min-width: 375px) and (max-width: 383px) {
      html {
        font-size: 100px; } }
    @media screen and (min-width: 384px) and (max-width: 399px) {
      html {
        font-size: 102.4px; } }
    @media screen and (min-width: 400px) and (max-width: 413px) {
      html {
        font-size: 106.66667px; } }
    @media screen and (min-width: 414px) {
      html {
        font-size: 110.4px; } }
    /*css reset*/
    body,
    div,
    dl,
    dt,
    dd,
    ul,
    ol,
    li,
    h1,
    h2,
    h3,
    h4,
    h5,
    h6,
    pre,
    code,
    form,
    fieldset,
    legend,
    input,
    textarea,
    p,
    blockquote,
    th,
    td,
    header,
    hgroup,
    nav,
    section,
    article,
    aside,
    footer,
    figure,
    figcaption,
    menu,
    button {
      margin: 0;
      padding: 0; }
    li{
      list-style: none;
    }
    #app{
      width: 100%;
      max-width: 640px;
     }
    li {
      height: 1.2rem;
      width: 100%;
      border-bottom: 1px solid #cccccc;
      text-align: center;
      line-height: 1.2rem;
      font-size: 20px;
    }
  </style>
  <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>

</head>
<body>
  <div id="app">
    <ul>
      <li data-page="1" data-url="http://baidu.com?id=1">第一页 第1个li</li>
      <li data-page="1" data-url="http://baidu.com?id=2">第一页 第2个li</li>
      <li data-page="1" data-url="http://baidu.com?id=3">第一页 第3个li</li>
      <li data-page="1" data-url="http://baidu.com?id=4">第一页 第4个li</li>
      <li data-page="1" data-url="http://baidu.com?id=5">第一页 第5个li</li>
      <li data-page="1" data-url="http://baidu.com?id=6">第一页 第6个li</li>
      <li data-page="1" data-url="http://baidu.com?id=7">第一页 第7个li</li>
      <li data-page="1" data-url="http://baidu.com?id=8">第一页 第8个li</li>
      <li data-page="1" data-url="http://baidu.com?id=9">第一页 第9个li</li>
      <li data-page="1" data-url="http://baidu.com?id=10">第一页 第10个li</li>
      <li data-page="1" data-url="http://baidu.com?id=11">第一页 第11个li</li>
      <li data-page="1" data-url="http://baidu.com?id=12">第一页 第12个li</li>
      <li data-page="1" data-url="http://baidu.com?id=13">第一页 第13个li</li>
      <li data-page="1" data-url="http://baidu.com?id=14">第一页 第14个li</li>
      <li data-page="1" data-url="http://baidu.com?id=15">第一页 第15个li</li>

      <li data-page="2" data-url="http://baidu.com?id=16">第二页 第1个li</li>
      <li data-page="2" data-url="http://baidu.com?id=17">第二页 第2个li</li>
      <li data-page="2" data-url="http://baidu.com?id=18">第二页 第3个li</li>
      <li data-page="2" data-url="http://baidu.com?id=19">第二页 第4个li</li>
      <li data-page="2" data-url="http://baidu.com?id=20">第二页 第5个li</li>
      <li data-page="2" data-url="http://baidu.com?id=21">第二页 第6个li</li>
      <li data-page="2" data-url="http://baidu.com?id=22">第二页 第7个li</li>
      <li data-page="2" data-url="http://baidu.com?id=23">第二页 第8个li</li>
      <li data-page="2" data-url="http://baidu.com?id=24">第二页 第9个li</li>
      <li data-page="2" data-url="http://baidu.com?id=25">第二页 第10个li</li>
      <li data-page="2" data-url="http://baidu.com?id=26">第二页 第11个li</li>
      <li data-page="2" data-url="http://baidu.com?id=27">第二页 第12个li</li>
      <li data-page="2" data-url="http://baidu.com?id=28">第二页 第13个li</li>
      <li data-page="2" data-url="http://baidu.com?id=29">第二页 第14个li</li>
      <li data-page="2" data-url="http://baidu.com?id=30">第二页 第15个li</li>
    </ul>
  </div>
</body>
<script type="text/javascript">
  /*
   * 1.为什么我要返回定位呢。肯定是增加用户的体验度。比如你刚看的那条信息挺感
   * 兴趣的,点进详情看完了,回来一看,不见了,是不是很呕心啊。
   * 2.难点在哪里?
   *  难点1:当我们有很多的列表的时候,列表肯定是滚动加载。于是我们直接保存滚动条的位置
   *  的方式可以放弃了。
   *  难点2:我们怎么确定是从详情返回来的?
   * 3.我们该怎么实现呢?
   *  其实我们实现的方式跟保存滚动条的位置差不多。但要对scrolltop的距离进行处理。
   *  a.我们点击这点详情的时候,可视区域列表的条数,可以是一页的数据,可能会是2页数据。
   *  这种情况下我们都要把结果保留下来。
   *  b.当我们点击这条数据的时候存现当前页滚动了多少就可以了。
   *
   *  下面具体看代码:
   */
  (function(global,$,factory){
    var keepscrolltop = 0; //用于最后保存的滚动条的位置
    var tool =factory();
    $.fn.saveposition = function(options){
      var datapage,logo,objlogo,prevnum,containerheight = 0,scrolltopdistance = 0,elindex = 0,
       prevheight = 0,prevcountpage = 0,prevcountpagedistance = 0,prevdistance = 0,
       prevpagescrolldistance = 0;
      var elements = this;
      var defaults = {
        container:$(window),  //滚动的容器
        logo:"data-url",   // 用于计算在这个容器中的每个li中的唯一标识量。一般为去详情的连接
        currentpage:"data-page",  //点击当前的li的页码
        pageresize:30,        //与后台交互的每页返回的数量。 默认是30,
        gotodetailelement:$(".go-detail") ,  //滚动的每个列的总对象
        nodeli:"", //元素节点
        getpagenum:"getpagenum",       //1表示单页数据,2表示双页数据。设置是请求单页数据还是双页数据的标识量。放在url上。
        urlpagenum:"pagenum",        //用于放到url上面的参数标识表示当前是几页. pagenum = currentpage  //返回来的时候用这个参数来判断是不是需要滚动
      };
      var settings = $.extend(defaults,options || {});
      datapage = elements.attr(settings.currentpage);  //求出点击对象位于哪一个页码
      logo = elements.attr(settings.logo);   //求出当前对象的唯一标识量
      containerheight = parseint(settings.container.outerheight());  //容器的高度
      scrolltopdistance = parseint(settings.container.scrolltop()); //滚动的距离
      elements.parent().find(""+ settings.nodeli + "["+settings.currentpage + "=" + datapage +"]").each(function(index, obj){
        objlogo = $(obj).attr(settings.logo);
        elindex = index;
        if(logo == objlogo){
          prevnum = elements.prevall().length;
          prevheight = tool.getdistance(elements.parent().children(),prevnum - elindex);
          prevcountpage = parseint(prevnum / settings.pageresize);
          if(scrolltopdistance < prevheight){
            elements.parent().children().each(function(index,target){
              if(prevcountpage > 0 ){
                if(index < (prevcountpage - 1) * settings.pageresize){
                  prevcountpagedistance += parseint($(target).outerheight());
                };
              };
            });
            tool.changeurlpar(settings.urlpagenum,datapage - 1);     //当前的页数
            tool.changeurlpar(settings.getpagenum,2);       //获取双页数据
            keepscrolltop = scrolltopdistance - prevcountpagedistance;          //请求双页数据 向上 减 1;
          }else{
            prevdistance = tool.getdistance(elements.parent().children(),(prevcountpage + 1) * settings.pageresize);
            prevpagescrolldistance = tool.getdistance(elements.parent().children(),prevcountpage * settings.pageresize);
            if(prevdistance < (scrolltopdistance + containerheight)){
              tool.changeurlpar(settings.urlpagenum,datapage);    //点击对象位于当前的页数
              tool.changeurlpar(settings.getpagenum,2);        //请求双页数据
              keepscrolltop = scrolltopdistance - prevpagescrolldistance;
            }else{
              tool.changeurlpar(settings.urlpagenum,datapage);    //点击对象位于当前的页数
              tool.changeurlpar(settings.getpagenum,1);  //请求单页数据
              keepscrolltop = scrolltopdistance - prevpagescrolldistance;
            };
          };
        };
      });
      tool.setsessionstorage("keepscrolltop",keepscrolltop);   //保存滚动条的位置
      return this;
    };
    $.getsessionstorage = function(opt){
      opt = sessionstorage.getitem(opt);
      return opt;
    };
  })(window,jquery,function(){
    var tool = {
      changeurlpar(arg, val){  //改变url参数
        function changeu(destiny, par, par_value) {
          var pattern = par+'=([^&]*)';
          var replacetext = par+'='+par_value;
          if (destiny.match(pattern))
          {
            var tmp = '/\\'+par+'=[^&]*/';
            tmp = destiny.replace(eval(tmp), replacetext);
            return (tmp);
          }
          else {
            if (destiny.match('[\?]'))
            {
              return destiny+'&'+ replacetext;
            }
            else
            {
              return destiny+'?'+replacetext;
            }
          }
          return destiny+'\n'+par+'\n'+par_value;
        }
        var hash = window.location.hash;
        history.replacestate(null,'',location.pathname+location.search);
        url = window.location.href;
        var newurl = changeu(url,arg,val) + hash;
        history.replacestate(null,'',newurl);
        return false;
      },
      removeurlpar(options){
        history.replacestate(null,'',location.pathname+location.search);
        var newparamstr = "";
        var quotes = window.location.href.indexof("?");
        if(quotes != -1){
          var weburl = window.location.href.split("?")[0];
          var paramsstr = window.location.href.split("?")[1].tostring();
          if(paramsstr.indexof("&") != -1){
            var pageindex = paramsstr.indexof(options);
            if(pageindex != -1){
              var pagearr = paramsstr.split("&");
              for(var i = 0; i < pagearr.length; i++){
                if(pagearr[i].match(options)){
                  pagearr.splice(i,1);
                };
              };
              newparamstr = pagearr.join("&");
            }else{
              newparamstr = paramsstr;
            } ;

          }else{
            if(paramsstr.match(options)){
              newparamstr = "";
            }else {
              newparamstr = paramsstr;
            };
          };
          history.replacestate(null,'',weburl + "?" + newparamstr);
        }else{
          history.replacestate(null,'',w.location.href);
        }
      },
      getdistance(obj,maxnum){
        var h = 0;
        obj.each(function(index,target){
          if(index < maxnum){
            h += parseint($(target).outerheight());
          }
        });
        return h;
      },
      setsessionstorage(keyname,opt){
        sessionstorage.setitem(keyname,opt);
        console.log(opt)
      },
    }

    return tool;
  })
  $("li").on("click",function(){
    $(this).saveposition({pageresize:15});
    /*
     *  1.http://localhost/index.php/home/web?pagenum=2&getpagenum=1
     * 点击玩了以后url就变成这样了。这时候表示 返回来的时候请求第二页的数据。只请求一次。从第二页开始
     *
     * 2.http://localhost/index.php/home/web?pagenum=1&getpagenum=2
     * 这样表示请求也数据。从第一页的数据开始
     *
     */
    var _herf = $(this).attr("data-url");
    window.location.href = _herf;
  });
  //当我们初始化的时候
  var pagenum = 1,getpagenum = 2; //这两个数的值是从url中获取的。只有从详情返回来 时候,才有

  if(!!pagenum && !!getpagenum){
    //其中还有很多判定,肯定是先获取数据在滚动。。。
    $(window).scrolltop($.getsessionstorage('keepscrolltop'));
  }else{

  }
</script>
</html>

这个返回定位的插件基本就开发完毕了。当然对于实际的项目中,还有很多的改动。比如返回的时候,一定要把设置的标志参数去掉。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!