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 相关文章推荐
javascript 当前日期加(天、周、月、年)
Aug 09 Javascript
JQquery的一些使用心得分享
Aug 01 Javascript
javascript中的缓动效果实现程序
Dec 29 Javascript
JS弹出层单纯的绝对定位居中示例代码
Feb 18 Javascript
jQuery实现的精美平滑二级下拉菜单效果代码
Mar 28 Javascript
jQuery对checkbox 复选框的全选全不选反选的操作
Aug 09 Javascript
JavaScript性能优化之函数节流(throttle)与函数去抖(debounce)
Aug 11 Javascript
Ionic默认的Tabs模板使用实例
Aug 29 Javascript
Bootstrap整体框架之CSS12栅格系统
Dec 15 Javascript
layer弹出层取消遮罩的方法
Sep 25 Javascript
Centos7 安装Node.js10以上版本的方法步骤
Oct 15 Javascript
Vue循环遍历选项赋值到对应控件的实现方法
Jun 22 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动态创建Flash动画
2006/10/09 PHP
更改localhost为其他名字的方法
2014/02/10 PHP
Yii中CGridView实现批量删除的方法
2015/12/28 PHP
PHP入门教程之操作符与控制结构流程详解
2016/09/09 PHP
HTML IMG标签 onload 内存溢出导致浏览器CPU占用过高
2021/03/09 Javascript
巧妙破除网页右键禁用的十大绝招
2006/08/12 Javascript
jQuery load方法用法集锦
2011/12/06 Javascript
JS的数组迭代方法
2015/02/05 Javascript
jquery对dom节点的操作【推荐】
2016/04/15 Javascript
js实现人民币大写金额形式转换
2016/04/27 Javascript
解析JavaScript面向对象概念中的Object类型与作用域
2016/05/10 Javascript
JavaScript蒙板(model)功能的简单实现代码
2016/08/04 Javascript
同步异步动态引入js文件的几种方法总结
2016/09/23 Javascript
Vue框架中正确引入JS库的方法介绍
2017/07/30 Javascript
浏览器调试动态js脚本的方法(图解)
2018/01/19 Javascript
JS实现对json对象排序并删除id相同项功能示例
2018/04/18 Javascript
Vue一次性简洁明了引入所有公共组件的方法
2018/11/28 Javascript
微信小程序实现发送验证码按钮效果
2018/12/20 Javascript
解决layer图标icon不加载的问题
2019/09/04 Javascript
Python标准库与第三方库详解
2014/07/22 Python
Python的动态重新封装的教程
2015/04/11 Python
Python通过for循环理解迭代器和生成器实例详解
2019/02/16 Python
pandas基于时间序列的固定时间间隔求均值的方法
2019/07/04 Python
Python Sphinx使用实例及问题解决
2020/01/17 Python
纯CSS3绘制打火机动画火焰效果
2016/07/18 HTML / CSS
纯css3使用vw和vh实现自适应的方法
2018/02/09 HTML / CSS
世界上最大的汽车共享网站:Zipcar
2017/01/14 全球购物
巴西电子、家电、智能手机购物网站:Girafa
2019/06/04 全球购物
Spartoo美国:欧洲排名第一的在线时装零售商
2019/12/12 全球购物
婚礼新郎父母答谢词
2014/01/16 职场文书
消防安全员岗位职责
2014/03/10 职场文书
幼儿园家长安全责任书
2014/07/22 职场文书
2014年心理健康教育工作总结
2014/12/06 职场文书
2015年端午节活动总结
2015/02/11 职场文书
vue如何批量引入组件、注册和使用详解
2021/05/12 Vue.js
Redis高级数据类型Hyperloglog、Bitmap的使用
2021/05/24 Redis