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 密码强弱度检测万能插件
Feb 25 Javascript
jquery.AutoComplete.js中文修正版(支持firefox)
Apr 09 Javascript
js函数排序的实例代码
Jul 01 Javascript
实测jquery data()如何存值
Aug 18 Javascript
JQuery1.8 判断元素是否绑定事件的方法
Jul 10 Javascript
JQuery右键菜单插件ContextMenu使用指南
Dec 19 Javascript
javascript定义变量时加var与不加var的区别
Dec 22 Javascript
js获取页面及个元素高度、宽度的代码
Apr 26 Javascript
jquery checkbox无法用attr()二次勾选问题的解决方法
Jul 22 Javascript
JS基于正则实现数字千分位用逗号分隔的方法
Jun 16 Javascript
使用D3.js+Vue实现一个简单的柱形图
Aug 05 Javascript
解决微信小程序调用moveToLocation失效问题【超简单】
Apr 12 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
实现在同一方法中获取当前方法中新赋值的session值解决方法
2014/06/26 PHP
Yii2中OAuth扩展及QQ互联登录实现方法
2016/05/16 PHP
PHP mysqli_free_result()与mysqli_fetch_array()函数详解
2016/09/21 PHP
使用php自动备份数据库表的实现方法
2017/07/28 PHP
PHP创建对象的六种方式实例总结
2019/06/27 PHP
jQuery+CSS 实现的超Sexy下拉菜单
2010/01/17 Javascript
Firefox下提示illegal character并出现乱码的原因
2010/03/25 Javascript
javascript面向对象之Javascript 继承
2010/05/04 Javascript
三种动态加载js的jquery实例代码另附去除js方法
2014/04/30 Javascript
js判断图片加载完成后获取图片实际宽高的方法
2016/02/25 Javascript
vue使用ElementUI时导航栏默认展开功能的实现
2018/07/04 Javascript
详解Vue2 添加对scss的支持
2019/01/02 Javascript
解决前后端分离 vue+springboot 跨域 session+cookie失效问题
2019/05/13 Javascript
VUE组件中的 Drawer 抽屉实现代码
2019/08/06 Javascript
vue使用高德地图根据坐标定位点的实现代码
2019/08/22 Javascript
vue中使用elementUI组件手动上传图片功能
2019/12/13 Javascript
Websocket 向指定用户发消息的方法
2020/01/09 Javascript
详解Python进程间通信之命名管道
2017/08/28 Python
Flask框架Flask-Principal基本用法实例分析
2018/07/23 Python
python找出完数的方法
2018/11/12 Python
对Python中画图时候的线类型详解
2019/07/07 Python
python GUI库图形界面开发之PyQt5多行文本框控件QTextEdit详细使用方法实例
2020/02/28 Python
HTML5之多线程(Web Worker)
2019/01/02 HTML / CSS
浅析HTML5中的download属性使用
2019/03/13 HTML / CSS
希尔顿酒店官方网站:Hilton Hotels
2017/06/01 全球购物
瑞士首家网上药店折扣店:McDrogerie
2020/12/22 全球购物
我的applet原先好好的, 一放到web server就会有问题,为什么?
2016/05/10 面试题
char型变量中能不能存贮一个中文汉字
2015/07/08 面试题
Java里面StringBuilder和StringBuffer有什么区别
2016/06/06 面试题
百度JavaScript笔试题
2015/01/15 面试题
即兴演讲稿
2014/01/04 职场文书
出生医学证明样本
2014/01/17 职场文书
毕业生对母校寄语
2015/02/26 职场文书
2015年119消防宣传日活动总结
2015/03/24 职场文书
大学开学典礼新闻稿
2015/07/17 职场文书
《只有一个地球》教学反思
2016/02/16 职场文书