最近经常与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);





jquery插件,美化select标签的更多相关文章

  1. jquery插件-自定义select

        由于原生select在各个浏览器的样式不统一,特别是在IE67下直接不可以使用样式控制,当PM让你做一个样式的时候,那是相当的痛苦.最好的办法就是使用自定义样式仿select效果.这里写了一个 ...

  2. jQuery插件实现select下拉框左右选择_交换内容(multiselect2side)

    效果图: 使用jQuery插件---multiselect2side做法: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitio ...

  3. jquery插件:select、checkbox、radio的美化

    引用文件:  <script src=”/InputPick/jqInputFormat.js” type=”text/javascript”></script> <li ...

  4. jquery插件之tab标签页或滑动门

    该插件乃本博客作者所写,目的在于提升作者的js能力,也给一些js菜鸟在使用插件时提供一些便利,老鸟就悠然地飞过吧. 此插件旨在实现目前较为流行的tab标签页或滑动门特效,在此插件中默认使用的是鼠标滑过 ...

  5. 网站开发常用jQuery插件总结(八)标签编辑插件Tagit

    一.Tagit插件功能 提高网站交互性,增加用户体验.至于其它的功能,还真没有.用一个input text就可以替换了它.但是text没有输入提示功能,而tagit拥有这个功能.官方示例如下图: 将关 ...

  6. css美化select标签,兼容ie10 ie10+,chrome。但不支持ie9 ie9-

    让ie9 ie9+ 和非ie的浏览器加载这个hack.ie8,ie8- 就用自己的默认样式 <!-- email:416960428@qq.com author:李可 --> <!- ...

  7. jQuery插件综合应用(三)发布文章页面

    一.使用的插件 一个折叠的功能导航,由Akordeon插件实现.Nanoscroller插件与Tagit插件主要用于美化页面.这里只是测试,其实还可以综合使用其它的插件,例如将Akordeon插件换成 ...

  8. 美化select的jquery插件

    自己写的一个美化select插件,浏览器自带的实在太丑,还不能用css自定义. 插件主要原理是隐藏原生的select控件,支持select上设置change事件. 脚本 /* * iSelect * ...

  9. JQCloud: 一个前端生成美化标签云的简单JQuery插件

    本文原文地址:https://jiang-hao.com/articles/2018/blog-JQCloud.html 因为博客需要,发现了一个生成美化简约风格的标签云的JQuery插件. 官网地址 ...

随机推荐

  1. 课程助理For Windows(预览版,正方教务系统学生查分工具)

    其实盖子已经开发了一个功能更强大的版本,但是那个版本依然基于正方系统,也就是说只要正方系统跪了或者张院士在网站上做点手脚,这个小工具就会失效. 今天给大家的版本虽然功能及其简单.界面极端丑陋,但是通过 ...

  2. 用JAX-WS在Tomcat中公布WebService

    JDK中已经内置了Webservice公布,只是要用Tomcat等Webserver公布WebService,还须要用第三方Webservice框架. Axis2和CXF是眼下最流行的Webservi ...

  3. jquerymobile知识点:动态ListView

    这里要讲的是jqueryMobile 中的ListView 动态的列表 <ul data-role="listview" data-inset="true" ...

  4. hibernate.hbm.xml配置文件内容说明

    下面是一个自动生成的配置文件: <?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE hibernate-configuration PU ...

  5. 使用SBT构建Scala项目

    既然决定要在Scala上下功夫,那就要下的彻底.我们入乡随俗,学一下SBT.sbt使用ivy作为库管理工具.ivy默认把library repository建在user home下面. 安装SBT 在 ...

  6. Abstract Factory 抽象工厂模式

    提供一个创建一些列相关或相互依赖对象的接口,而无需指定它们具体的类. 抽象工厂顾名思义就是对工厂的抽象,它提供了一组创建抽象产品对象的操作接口,我们实际使用的是抽象工厂的派生类,派生类中提供了操作的具 ...

  7. sql like '%x%'优化

    好久没写点什么了.唉(此处省略无数,一切尽在苦逼中...) 说说sql中的全匹配优化吧.在sql server进行模糊查询的时候,如果是进行全匹配的话,那么肯定会用到like.我们知道like '%张 ...

  8. Node.js + Express + Mongodb 开发搭建个人网站(三)

    三.后台架构 1.在根目录下(和 views 文件夹同级)创建 lib 文件夹 以后所有后端内容 都是在这里写,分别创建三个文件夹 到 lib 目录下: mongo  放的是数据的存储 module  ...

  9. servlet HttpSession 监听器

    一.Servlet中对象作用域 1. ServletContext 上下文 应用服务器一启动就产生该对象,服务器关闭即销毁 作用于全局,所有Servlet ,相当于静态变量 2. HttpSessio ...

  10. C# DbHelperSQLP,操作不同的数据库帮助类 (转载)

    本类主要是用来访问不同数据库而编写的主要功能如下 .数据访问基础类(基于不同数据库),主要是用来访问不同数据库的. .得到最大值:是否存在:是否存在: . 执行SQL和Orace语句,返回影响的记录数 ...