select标签模拟/美化方法采用JS外挂式插件


Posted in Javascript onApril 01, 2013

<select>标签的外观问题很恼人,各个浏览器都不一致,单单就IE,一个版本就一个长相,还不能用CSS修饰。

在这将本人对<select>的美化方法共享出来。
优点: 仍保留使用<select>,仅改变外观,不改变不干预Form行为,后期加载JS。(注:本脚本依赖jQuery)

啥也不说了,都在代码里。

 
$(document).ready(function () { 
// 找出需要美化的<select>标记,我们用一个class名称 "beautify" 来确定,没有这个样式的<select>则将被忽略 
var selects = $("select.beautify"); 
if (selects.length > 0) { 
//先在代码底部增加一个<div>,用来承载和显示下拉框选项 
$("body").append("<div id='dummydata' style='position:absolute; display:none'></div>"); 
//挨个美化呗 
selects.each(function () { 
//给本函数下的 this (也就是 <select>) 设置一个别名,在下面的匿名函数中将会被用到 
var select = this; 
//创建一个 <input> , .dummy 将用于我们对此类 <input> 进行专门样式定义 
//同时将 <select> 的部分属性和样式复制给这个 dummy input 
//创建完后,将这个 <input> 插入 dom, 紧跟原 <select> 
var input = $("<input type='text' readonly='readonly' class='input dummy' />") 
.attr("disabled", this.disabled) 
.css("width", parseInt(this.style.width) + "px") 
.css("display", this.style.display) 
.insertAfter(this) 
.val(this.options[this.selectedIndex].text); 
//将 <select> 藏掉,不要在 .beautify 中去定义 display:none, 因为js加载失败时,我们还得用上它 
this.style.display = "none"; 
// 当 <input class='dummy'> 被点击时 
input.click(function () { 
//调出前面创建的 <div id='dummydata'>,并清空内容 
//将 <select> 的样式表传递给它,当需要对这个 <div> 进行修饰时,就靠这些样式定义 
var div = $("#dummydata") 
.empty() 
.attr("class", select.className); 
//设置 <div> 的宽度 
//在这里我们判断一个特殊的class名 "extend" 
//如果带有 .extend,表示宽度将受额外自定义控制;否则,宽度将默认与 <input> 一致 
$(select).hasClass("extend") 
? div.css("width", "") 
: div.css("width", $(this).innerWidth()); 
//将 <option> 复制到 <div id='dummydata'> 里面,一个 <option> 对应一个 <a> 标记 
for (var i = 0; i < select.options.length; i++) { 
var item = select.options[i]; 
var a = $("<a href='javascript:void(0);' class='nowrap'></a>") 
.css("color", item.style.color) 
.addClass(item.className) 
.html(item.text) 
.appendTo(div); 
if (i == select.selectedIndex) { 
a.addClass("selected"); 
} 
//当选项被点击时,<input> 内容显示为对应 <option>,关闭 <div> 层,同时将事件冒泡给原来的 <select> 
a.click(function () { 
var n = $(this).index(); 
select.selectedIndex = n; 
input.val(select.options[n].text); 
div.hide(); 
$(select).change(); 
}); 
} 
//在这里我们判断一个特殊的class名 "noscroll" 
//当选项过多时,默认会让选项列表出现滚动条;但如果有 .noscroll 修饰,则强制不出现滚动条 
var noscroll = (select.options.length < 10 || $(select).hasClass("noscroll")); 
if (/msie 6/i.test(window.navigator.userAgent)) { 
div.css("height", noscroll ? "auto" : "215px").css("overflow-y", noscroll ? "hidden" : "scroll"); 
} else { 
div.css("max-height", noscroll ? "10000px" : "215px"); 
} 
//在这里我们判断一个特殊的class名 "onside" 
//如果有 .onside 修饰,弹出的选项层将在侧面,否则是在下面 
//注: 此处用到2个函数 locateBeside 和 locateBelow 是本人js库中的方法,稍等另外给出 
$(select).hasClass("onside") 
? div.locateBeside(this, -2) 
: div.locateBelow(this, -4); 
//对反复点击 <input> 之类的事情,做一些智能调节 
if (window.activeDummySelect == select) { 
div.slideToggle(100); 
} else { 
div.hide().slideDown(100); 
window.activeDummySelect = select; 
} 
//在有滚动条的情况下,我们需要将滚动条滚动到当前选中项的位置 
if (!select.selectedIndex > 6 && div[0].scrollHeight > div.height()) { 
div.scrollTop((select.selectedIndex - 3) * div[0].firstChild.offsetHeight); 
} 
}); 
}); 
//最后别忘了:点击网页上的游离区域时,应该隐藏<div #dummydata> 
$(document).click(function (e) { 
if (!$(e.target).is(".dummy") && !$(e.target).is("#dummydata")) { 
$("#dummydata").hide(); 
} 
}); 
} 
});

上面代码里说用到了2个方法: locateBeside 和 locateBelow, 是本人js库中对 jQuery 的扩展,顺便多赠送2个方法 locate 和 locateCenter
:-)  代码如下:
$.fn.extend({ 
locate: function (x, y) { 
if (this.css("position") == "fixed") { 
y -= $(document).scrollTop(); 
} 
return this.css({ left: x, top: y }); 
}, 
locateBeside: function (el, adjustX) { 
var p = $(el).offset(), 
w1 = $(el).outerWidth(), 
w2 = this.outerWidth(), 
h2 = this.outerHeight(), 
x = p.left + w1 + 5 + (adjustX || 0), 
y = p.top; 
if ($(document).width() < x + w2) { 
x = p.left - w2 - 5 - (adjustX || 0); 
} 
if ($(document).height() < y + h2) { 
y = p.top - (y + h2 + 15 - $(document).height()); 
} 
return this.locate(x, y); 
}, 
locateBelow: function (el, adjustY) { 
var p = $(el).offset(); 
return this.locate(p.left, p.top + $(el).outerHeight() + 3 + (adjustY || 0)); 
}, 
locateCenter: function () { 
return this.locate( 
($(window).width() - this.width()) / 2, 
($(window).height() - this.height()) / 2 + $(document).scrollTop() 
); 
} 
});

最后给出一些样式表定义的例子,以及演示效果:
input.dummy { background-image: url(/static/images/combo.gif); background-position: right 12px; background-repeat: no-repeat; cursor: pointer !important; } 
input.dummy:hover, input.dummy:focus { background-image: url(/static/images/combo_hover.gif); } 
#dummydata { position: absolute; z-index: 20; border: 1px solid #a4601e; background-color: #393939; max-height: 200px; overflow: auto; } 
#dummydata a { display: block; color: #ddd; line-height: 25px; text-indent: 3px; text-overflow: ellipsis; } 
#dummydata a:hover { color: #198cef; text-decoration: none; } 
#dummydata.matrix { width: 208px; padding: 5px; } /* matrix 效果 */ 
#dummydata.matrix a { float: left; width: 33%; } 
#dummydata.matrix-large { width: 640px; padding: 5px; } /* matrix-large 效果 */ 
#dummydata.matrix-large a { float: left; width: 25%; } 
#dummydata a.fullwidth { float: none; } 
#dummydata a.delimiter { float: none; width: 100%; height: 10px; visibility: hidden; } 
#dummydata a.selected { color: yellow; }

上面样式定义的效果图

select标签模拟/美化方法采用JS外挂式插件 select标签模拟/美化方法采用JS外挂式插件select标签模拟/美化方法采用JS外挂式插件
html中要做的,只是加几个class修饰

select标签模拟/美化方法采用JS外挂式插件

Javascript 相关文章推荐
Prototype使用指南之base.js
Jan 10 Javascript
window.location不跳转的问题解决方法
Apr 17 Javascript
JQuery弹出炫丽对话框的同时让背景变灰色
May 22 Javascript
推荐一款jQuery插件模板
Jan 09 Javascript
jQuery插件制作之全局函数用法实例
Jun 01 Javascript
angular-cli修改端口号【angular2】
Apr 19 Javascript
vue自定义tap指令及tap事件的实现
Sep 18 Javascript
在vue里使用codemirror遇到的问题
Nov 01 Javascript
使用Vue.set()方法实现响应式修改数组数据步骤
Nov 09 Javascript
vue路由结构可设一层方便动态添加路由操作
Aug 31 Javascript
Vue-Ant Design Vue-普通及自定义校验实例
Oct 24 Javascript
微信小程序实现分页加载效果
Nov 19 Javascript
html组件不可输入(只读)同时任何组件都有效
Apr 01 #Javascript
jQuery 网易相册鼠标移动显示隐藏效果实现代码
Mar 31 #Javascript
jQuery实现页面滚动时层智能浮动定位实例探讨
Mar 29 #Javascript
表单验证的完整应用案例探讨
Mar 29 #Javascript
JavaScript 处理Iframe自适应高度(同或不同域名下)
Mar 29 #Javascript
图片img的src不变让浏览器重新加载实现方法
Mar 29 #Javascript
javascript打印大全(打印页面设置/打印预览代码)
Mar 29 #Javascript
You might like
php 分页原理详解
2009/08/21 PHP
php生成固定长度纯数字编码的方法
2015/07/09 PHP
Yii框架通过请求组件处理get,post请求的方法分析
2019/09/03 PHP
JSON+JavaScript处理JSON的简单例子
2013/03/20 Javascript
放弃用你的InnerHTML来输出HTML吧 jQuery Tmpl不详细讲解
2013/04/20 Javascript
使用jQuery UI的tooltip函数修饰title属性的气泡悬浮框
2013/06/24 Javascript
jQuery控制iFrame(实例代码)
2013/11/19 Javascript
使用cluster 将自己的Node服务器扩展为多线程服务器
2014/11/10 Javascript
如何实现chrome浏览器关闭页面时弹出“确定要离开此面吗?”
2015/03/05 Javascript
Ionic 2 实现列表滑动删除按钮的方法
2017/01/22 Javascript
ReactJs实现树形结构的数据显示的组件的示例
2017/08/18 Javascript
Vue仿手机qq的实例代码(demo)
2017/09/08 Javascript
webpack项目调试以及独立打包配置文件的方法
2018/02/28 Javascript
基于layui数据表格以及传数据的方式
2018/08/19 Javascript
js字符串类型String常用操作实例总结
2019/07/05 Javascript
微信小程序事件 bindtap bindinput代码实例
2019/08/26 Javascript
Layui带搜索的下拉框的使用以及动态数据绑定方法
2019/09/28 Javascript
vue实现广告栏上下滚动效果
2020/11/26 Vue.js
[38:23]2014 DOTA2国际邀请赛中国区预选赛 5 23 CIS VS LGD第一场
2014/05/24 DOTA
python实现socket客户端和服务端简单示例
2014/02/24 Python
跟老齐学Python之重回函数
2014/10/10 Python
Python中实现对Timestamp和Datetime及UTC时间之间的转换
2015/04/08 Python
利用Pandas 创建空的DataFrame方法
2018/04/08 Python
Python数据分析库pandas基本操作方法
2018/04/08 Python
python读取文本绘制动态速度曲线
2018/06/21 Python
python 切换root 执行命令的方法
2019/01/19 Python
Django import export实现数据库导入导出方式
2020/04/03 Python
完美解决Django2.0中models下的ForeignKey()问题
2020/05/19 Python
python实现图片,视频人脸识别(dlib版)
2020/11/18 Python
土耳其新趋势女装购物网站:Addax
2020/01/07 全球购物
党员一句话承诺大全
2014/03/28 职场文书
应聘英语教师求职信
2014/04/24 职场文书
节约用水标语
2014/06/11 职场文书
国庆节慰问信
2015/02/15 职场文书
JUnit5常用注解的使用
2021/07/02 Java/Android
Prometheus 监控MySQL使用grafana展示
2021/08/30 MySQL