• jquery插件,美化select标签


          最近经常与select打交道,因为ie下的select实在太丑了,css怎么搞都搞不好看,因为程序已经写得差不多了,要再去模拟select改动太大,就想着能否不改动select,同时美化它。借鉴一下这篇文章js美化select,然后自己写了一个jquery插件,补充了一些功能。

          原理(这里就直接copy啦):

       第一步:将表单中的select隐藏起来。 
       第二步:用脚本找到select标签在网页上的绝对位置。 我们在那个位置上用DIV标签做个假的、好看点的来当他的替身。 
       第三步:用脚本把select标签中的值读出来。 虽然藏起来了,但它里边的options我们还有用呢,统统取出来。
       第四步:当用户点击select标签的替身,也就是div的时候。我们再用一个div浮在上一个div的下边,这个就是options的替身了。 

          说白了,就是弄一个div把原来的select完整遮住,然后实现弹出层和原来的option交互,难点就是交互。

    本文不打算讲怎么实现,源码里有注释,主要是分享,顺便说下几个需要注意的问题以及使用方法,小弟语文渣,凑合着看吧。。。

    所有代码全部打包在csdn下载那里,无需积分,下载地址

        先贴张效果图chrome,ff,ie,电脑上还是ie11的,ie大家不用说吧,做兼容性,select万恶啊。

        

       使用方法

        包含jquery.js,我用的1.8,然后包含jquery.beautifySelect.js,完整html测试代码

        html代码: 

    1
    2
    3
    4
    5
    <div style="margin:20px;">
         <select id="sel1"></select>
         <select id="sel2"></select>
         <button onclick="redraw()">重绘</button>
    </div>

        sel1是要覆盖的select,sel2作为对比。button测试select内容发生变化重新覆盖。

       

        js代码:    

        添加select

    1
    2
    3
    4
    5
    6
    var _html = "";
    for(var i = 0;i<22;++i){
        _html += "<option>" +i+"闲来无事写插件"+"</option>";
    }
    document.getElementById("sel1").innerHTML = _html;
    document.getElementById("sel2").innerHTML = _html;

            

          调用

    1
    2
    3
    4
    5
    6
    7
    8
    $("#sel1").beautifySelect({
        "maxShowItemNum" : 9,
        "downIcon" "url(down.png)  right  no-repeat",
        "upIcon" "url(up.png) right  no-repeat"
    });
    $("#sel1").change(function(){
        console.log(this.value+"改变");//观察事件
    });

           顺带测试select内容发生变化后的重绘
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    function redraw(){
        //如果select内容发生变化,相应重绘部分
        var _html = "";
        for(var i = 0 ;i<13;++i){
            _html += "<option>" +i+"内容改变啦""</option>";
        }
        document.getElementById("sel1").innerHTML = _html;
        $("#sel1").beautifySelect({
            "sDivStyle" : {
                "border" "1px solid red"
            }
        });
    }
           
            调用方法很简单,基本上使用过插件就知道,这里简单说下,maxShowItemNum是下拉框最大显示条数
    downIcon是向下折叠图标,upIcon是向上折叠图标。这里就是css样式,可以修改select样式,下面是全部样式,有注释就不细说了。

           可供选择入参
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    var defaultParObj = {
        "maxShowItemNum" : 10,//默认最多显示10条
        "sDivStyle" : {//select覆盖层样式
            "border" "1px solid #A5A5A5",
            "fontSize" "12px",
            "cursor" "default"
        },
        "hDivStyle" : {//弹出层,即下拉样式
            "border" "1px solid #7C99B7",
            "backgroundColor" "#FFF",
            "maxHeight" "200px",
            "overflowY" "auto"
        },
        "ulStyle" : {//因为用ul,li模拟的下拉,这里是ul的样式
            "fontSize" "12px"
        },
        "liStyle" : {//这是li的样式,就是每一条目
            "textIndent" "4px",
            "height" "20px",
            "lineHeight" "20px",
            "cursor" "default"
        },
        "liOnStyle": {//鼠标移上去的样式
            "backgroundColor" "#1E90FF",
            "color" "#FFF"
        },
        "liOffStyle" : {//鼠标移开的样式
            "backgroundColor" "#FFF",
            "color" "#000"
        }
        // "downIcon" : "url(...) 0 0",//向上图标
        // "upIcon" : "url(...) 0 0"//向下图标
    };
    注意:
    因为使用的div模拟的select,浏览器上,select失去焦点后会关闭下拉,这个暂时还没想到办法实现,以前做过笨方法,
    给body添加click事件,判断target,但是很慢。暂时不管吧,再来项目用模拟的,这个只是为了不改写好的事件做的美化。

    特点:
    除了上面说的不能失去焦点关闭,其他事件基本上都实现了,因为参照chrome的样式做的,不过提供属性,可以改样式。


    最后附上插件源码,第一次弄,格式老不对,就直接粘了吧,代码打个包放在那啥下载那儿,亲们,欢迎吐槽!
    下载链接csdn源代码下载
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    /**
     * @author 小余
     * 2014-08-30
     * 本插件基于jquery,为了美化select下拉框
     * 原理:
     * 第一步:将表单中的select隐藏起来。 
     * 第二步:用脚本找到select标签在网页上的绝对位置。 我们在那个位置上用DIV标签做个假的、好看点的来当他的替身。 
     * 第三步:用脚本把select标签中的值读出来。 虽然藏起来了,但它里边的options我们还有用呢,统统取过来。
     * 第四步:当用户点击select标签的替身,也就是div的时候。我们再用一个div浮在上一个div的下边,这个就是options的替身了。 
     * 调用举例:$("#selid").beautifySelect({
     *            "downIconUrl" : "ulr..",
     *            "upIconUrl"  : "url.."
     *            "sDivStyle" : {
     *           
     *             }
     * });
     * */
    ;
    (function ($) {
      $.fn.beautifySelect = function (attrObj) {
        var defaultParObj = {
          'maxShowItemNum': 10,
          //默认最多显示10条
          'sDivStyle': {
            'border''1px solid #A5A5A5',
            'fontSize''12px',
            'cursor''default'
          },
          'hDivStyle': {
            'border''1px solid #7C99B7',
            'backgroundColor''#FFF',
            'maxHeight''200px',
            'overflowY''auto'
          },
          'ulStyle': {
            'fontSize''12px'
          },
          'liStyle': {
            'textIndent''4px',
            'height''20px',
            'lineHeight''20px',
            'cursor''default'
          },
          'liOnStyle': {
            'backgroundColor''#1E90FF',
            'color''#FFF'
          },
          'liOffStyle': {
            'backgroundColor''#FFF',
            'color''#000'
          }
          // "downIcon" : "url(...) 0 0",//可入参
          // "upIcon" : "url(...) 0 0"
     
        };
        if (attrObj != undefined) {
          //合并
          for (var in attrObj) {
            if (typeof (attrObj[i]) != 'object') {
              defaultParObj[i] = attrObj[i];
            
            else defaultParObj[i] = $.extend(defaultParObj[i], attrObj[i]);
          }
        }
        //console.log(JSON.stringify(defaultParObj));
     
        var attrObj = defaultParObj;
        //设置弹出层高度
        var liHeight = attrObj.liStyle.lineHeight;
        //px
        attrObj.hDivStyle.maxHeight = attrObj.maxShowItemNum * parseInt(liHeight.slice(0, liHeight.indexOf('p'))) + 'px';
        var selectDom = this.get(0);
        //判断当前dom是否是select,不是提示使用错误
        if (selectDom.tagName != 'SELECT') {
          alert('使用错误,dom不是select对象');
          return ;
        }
        var selectPosObj = $.getAbsolutePos(selectDom);
        selectDom.style.visibility = 'hidden';
        //隐藏select,要占据位置
        //sDiv表示show的div,hDiv表示会hide的div,如果已经有,清空dom,删除事件,重新创建
        if (document.getElementById('selectOf' + selectDom.id) != null) {
          $('#selectOf' + selectDom.id) .remove();
          $('#selectChild' + selectDom.id) .remove();
        }
        var sDiv = document.createElement('div');
        sDiv.id = 'selectOf' + selectDom.id;
        sDiv.style.position = 'absolute';
        sDiv.style.width = selectPosObj.width + 'px';
        sDiv.style.height = selectPosObj.height + 'px';
        sDiv.style.top = selectPosObj.top + 'px';
        sDiv.style.left = selectPosObj.left + 'px';
        sDiv.style.lineHeight = selectPosObj.height + 'px';
        sDiv.style.cursor = 'default';
        for (var in attrObj.sDivStyle) {
          sDiv.style[i] = attrObj.sDivStyle[i];
        }
        if (attrObj.downIcon != undefined) {
          sDiv.style.background = attrObj.downIcon;
        }
        document.body.appendChild(sDiv);
        if (selectDom.selectedIndex == - 1) {
          alert('select未初始化');
          return ;
        }
        //select默认值传递给div
     
        sDiv.innerHTML = selectDom.options[selectDom.selectedIndex].innerHTML;
        var ifCreateHDiv = false;
        //是否创建过弹出层         
        sDiv.onclick = function () {
          if (ifCreateHDiv) {
            var hDiv = document.getElementById('selectChild' + selectDom.id);
            if (hDiv.style.display == 'none') {
              var index = selectDom.selectedIndex;
              for (var in attrObj.liOnStyle) {
                $(hDiv) .find('li:eq(' + index + ')') .get(0) .style[i] = attrObj.liOnStyle[i];
              };
              hDiv.style.display = '';
              //马上弹出
              if (attrObj.upIcon != undefined) sDiv.style.background = attrObj.upIcon;
              //向上折叠
            else {
              hDiv.style.display = 'none';
              if (attrObj.downIcon != undefined) sDiv.style.background = attrObj.downIcon;
              //向下折叠
            };
          else {
            //没有创建过,创建
            var hDiv = document.createElement('div');
            hDiv.id = 'selectChild' + selectDom.id;
            hDiv.style.position = 'absolute';
            hDiv.style.width = selectPosObj.width + 'px';
            hDiv.style.top = (selectPosObj.top + selectPosObj.height + 2) + 'px';
            hDiv.style.left = selectPosObj.left + 'px';
            for (var in attrObj.hDivStyle) {
              hDiv.style[i] = attrObj.hDivStyle[i];
            };
            //创建ul
            var ul = document.createElement('ul');
            ul.style.listStyle = 'none';
            ul.style.margin = '0';
            ul.style.padding = '0';
            for (var in attrObj.ulStyle) {
              ul.style[i] = attrObj.ulStyle[i];
            };
            hDiv.appendChild(ul);
            document.body.appendChild(hDiv);
            ifCreateHDiv = true;
            if (attrObj.upIcon != undefined) sDiv.style.background = attrObj.upIcon;
            //向上折叠
            for (var i = 0; i < selectDom.options.length; ++i) {
              var li = document.createElement('li');
              li.name = 'li' + i;
              //后面会用到
              li.innerHTML = selectDom.options[i].innerHTML;
              for (var in attrObj.liStyle) {
                li.style[j] = attrObj.liStyle[j];
              };
              ul.appendChild(li);
            };
            //默认填充第一个,那么默认第一个有样式
            for (var in attrObj.liOnStyle) {
              $(hDiv) .find('li:eq(0)') .get(0) .style[i] = attrObj.liOnStyle[i];
            }
            $(ul) .on('click''li'function () {
              document.getElementById('selectChild' + selectDom.id) .style.display = 'none';
              sDiv.innerHTML = this.innerHTML;
              var index = parseInt(this.name.slice(2));
              if (index != selectDom.selectedIndex) {
                selectDom.options[parseInt(this.name.slice(2))].selected = true;
                $(selectDom) .trigger('change');
              }
            });
            $(ul) .on('mouseenter''li'function () {
              var liDom = this;
              for (var in attrObj.liOnStyle) {
                liDom.style[i] = attrObj.liOnStyle[i];
              }
              //找到选中的li,弄掉样式,如果当前的li就是选中的li,就不弄掉
     
              var index = selectDom.selectedIndex;
              if (parseInt(liDom.name.slice(2)) != index) {
                for (var in attrObj.liOffStyle) {
                  $(ul) .find('li:eq(' + selectDom.selectedIndex + ')') .get(0) .style[i] = attrObj.liOffStyle[i];
                }
              }
            });
            $(ul) .on('mouseleave''li'function () {
              var liDom = this;
              for (var in attrObj.liOffStyle) {
                liDom.style[i] = attrObj.liOffStyle[i];
              }
            });
          }
        }
      };
      $.getAbsolutePos = function (dom) {
        //取标签的绝对位置,高度是内容高度
        var t = dom.offsetTop;
        var l = dom.offsetLeft;
        var w = dom.offsetWidth;
        var h = dom.offsetHeight - 2;
        //offsetHeight包括border
        while (dom = dom.offsetParent) {
          t += dom.offsetTop;
          l += dom.offsetLeft;
        }
        return {
          'top': t,
          'left': l,
          'width': w,
          'height': h
        }
      };
    }) (jQuery);






    stay hungry,stay foolish!生命不止,生无所息!
  • 相关阅读:
    js三种存储方式区别
    利用split方法计算字符串中出现字母最多的次数
    图片预加载的三个方法
    页面有大量图片,优化图片的加载方法
    USB通信协议——深入理解
    C/C++回调函数
    显卡工作原理
    include包含头文件的语句中,双引号和尖括号的区别是什么?
    华为2015校园招聘 上机试题
    位操作基础篇之位操作全面总结
  • 原文地址:https://www.cnblogs.com/AsuraRoute/p/3965165.html
Copyright © 2020-2023  润新知