美文网首页我爱编程
来,让我们用prototype和jq封装一个简单的tab小插件吧

来,让我们用prototype和jq封装一个简单的tab小插件吧

作者: 潘千千 | 来源:发表于2018-07-25 14:42 被阅读0次
    前言:最近公司后台需要实现一个类似于选项卡的一个搜索,比如说点击手机型号,下面出现很多选项如苹果华为等,点击其中一项,再下面一行会出现你点击的这个选项,当当当,就像下图这样:
    image.png

      点击搜索按钮,会收集选择结果那一行需要的数据传递给后台。由于这种形式的搜索在其他页面还会出现很多,所以,需要我把他们进行一下封装,前提是从后台接收到的数据结构都是一样的。

    关键词:$.fn $.extend prototype 选项卡 封装 ......

    正文:
    1、需求:
    运营提了要求,像很多插件一样,当他们想要用的时候,只需要在html里面写一个带有class的div,在script里面写入function然后传入数据就行:

    html:
    ......
    <div class="box"> </div>
    ......
    
    script:
    ......
    $('.box').tagRel({
         data:${dataValue}
     });
    ......
    
    js:
    (function($,window){
     function tagRel(element,options){
         this.element = $(element);
         this.options = $.extend({}, options);
         this._createDom();
         this._tabInit();
         this._tabToggle();
         this._labelClick();
         this._chosenClose();
     }
     tagRel.prototype = {
         //0:createDom
         _createDom : function(){
             var data = this.options.data,//要循环的数组
                 divHiddenForm = '',//隐藏域,放在this.element的前面
                 diva= '',
                 divb= '',
                 divc= '',
                 divaLi = '',//diva的tabli
                 divbPane = '';//divb的tab-pane
                 //divbPaneLi = '';//divb的tab-pane-li
             divHiddenForm = '<form id="searchForm" method="post" style="display:none">' +
                                 '<table class="search-table">' +
                                     '<tr>' +
                                         '<th>标签名称:</th>' +
                                         '<td><input id="hidden" name="condition" type="text"/></td>' +
                                     '</tr>' +
                                 '</table>' +
                             '</form>';
             //循环divaLi,divbPane
             $.each(data,function(i,item){
                 ......(省略)
             })
             diva = '<div class="title-box clearfix">'+
                         '<span class="labelValue">标签:</span>'+
                         '<ul class="tab-nav">'+divaLi+'</ul>'+
                     '</div>';
             divb = '<div class="tab-content">'+divbPane+'</div>';
             divc = '<div class="tab-footer clearfix">'+
                     '<span class="labelValue">选择结果:</span>'+
                     '<ul class="chosen-box"></ul>'+
                   '</div>';
             //1:this.element之前放入隐藏域
             this.element.before(divHiddenForm);
             //2:this.element里面放入tab-title-box
             this.element.append(diva);
             //3:this.element里面放入tab-content-box
             this.element.append(divb);
             //4:this.element里面放入tab-chosen-box
             this.element.append(divc);
         },
         //1:tab初始化
         _tabInit : function(){
             $('.tab-li').eq(0).addClass('active');//第一个标签默认选中#
             $('.tab-pane').eq(0).stop().fadeIn();//第一个div默认显示
         },
         //2:tab切换
         _tabToggle : function(){
             var self = this;
             $('.tab-li').click(function(e){
                 var liIndex = $(this).index();
                 $(this).addClass('active');
                 $(this).siblings().removeClass('active');
                 $('.tab-pane').hide();
                 $('.tab-pane').eq(liIndex).stop().fadeIn();
             })
         },
         //3:label点击
         _labelClick : function(e){
             ...(省略,这里就是一个点击标签,下层结果出现标签的效果)
         },
         //4:chosenClose关闭
         _chosenClose : function(e){
             var self= this;
             $(".layui-tab-close").live('click',function(e){
                 e.stopPropagation();
                 var dataId = $(this).closest('li').attr('data-id');
                 var targetli = $('.tab-content').find('li[data-id='+dataId+']');
                 targetli.removeClass('active');
                 $(this).closest('li').remove();
                 self._collection();
             })
         },
         //5:collect:收集结果
         _collection:function(){
             //收集信息
             var arr = [];
             $('.chosen-box li').each(function(){
                 var key = $(this).attr('data-tag'),
                     keyValue =$(this).attr('data-val'),
                     json = {};
                 json.tagName = key;
                 json.tagValue = keyValue;
                 arr.push(json);
             })//console.log(arr);//最终传输数据。
             $('#hidden').val(JSON.stringify(arr));
         }
     }
    
     $.fn.tagRel = function(options){
         new tagRel(this,options);
     }
    
    })(jQuery,window);
    

    好,上面是代码,下面就是几行重要代码的解析:
    先看下面这张图片,比较直观:


    image.png

    这张图片是上述代码收缩了部分,比较能够突出我要说的重点:

    重点一:

    我们用写插件的人的思维来思考,我们肯定是需要一个函数的,这个函数要接受到script里面传过来的参数。所以,我们先写一个函数。就是上图中的函数一。
    函数一接收了两个参数。一个是element,一个是options。element就代表着script里面是是哪个标签触发了这个函数,就是那个$(),里面是class。而options就是接收到的数据。

    重点二:

    $.extend({},options):
    $.extend()有两种用法
      一种是扩展方法。
      另一种是合并对象获得一个新的对象。
    这里,我们介绍一下合并对象这个方法:
    一般的插件中,比如说拖拽插件,表格插件,都会有一些默认的参数,那是在具体实例化时数据参数未传进来的时候,这些默认的参数不会让展示出来的页面看起来垮掉,哈哈。
    下面是找到的两个插件的默认参数default:
    拖拽插件:


    image.png

    表格插件:


    image.png
    大家是否觉得有点不一样,其实,细心的人发现,本质上两个是一样的,只不过表格插件是合起来写了。
    例如:
            var settings={validate:false,limit:5,name:"sm"};
            var defaults={validate:true,limit:2}
            var settings=$.extend(defaults,settings);
            结果:settings={validate:false,limit:5,name:"sm"}
    
    重点三:

    现在有了函数了,那么我们对于这个tab的一些操作都写在哪里呢,写在原型里吧,可随时取用。

    重点四:

    封装起来就可以了吗?不行的,因为我们每次传参数使用的时候是一个实例:
    所以,最后那个函数的意思如下:
    $.fn是指jquery的命名空间,加上fn上的方法及属性,会对jquery实例每一个有效。如扩展$.fn.abc()。
    在 jQuery 中,fn 其实就是 JavaScript 中 propotype 的一个别名,$ 是 jQuery 的别名,所以
    $.fn.tagRel等同于 jQuery.prototype.pluginName。举个简单的小例子:
    ('li') 是一个对象,它的 key 有 length,它的原型(共享属性)为 jQuery.prototype,jQuery.prototype 的 key 有 addClass、removeClass、text、html 和 on 等。 \.fn.tagRel表示创建一个 jQuery 的属性,通俗的说是写一个 jQuery 函数,tagRel才是函数名
    eg:

    $.fn.setRedText = function() {
        return $(this).css("color", "red");
    };
    $("p").setRedText();
    

    相关文章

      网友评论

        本文标题:来,让我们用prototype和jq封装一个简单的tab小插件吧

        本文链接:https://www.haomeiwen.com/subject/vnxpmftx.html