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 相关文章推荐
jquery右下角弹出提示框示例代码
Oct 08 Javascript
jquery实现效果比较好的table选中行颜色
Mar 25 Javascript
jQuery实现平滑滚动页面到指定锚点链接的方法
Jul 15 Javascript
js判断子窗体是否关闭的方法
Aug 11 Javascript
jQuery实现批量判断表单中文本框非空的方法(2种方法)
Dec 09 Javascript
学习javascript面向对象 掌握创建对象的9种方式
Jan 04 Javascript
Vuejs 实现简易 todoList 功能 与 组件实例代码
Sep 10 Javascript
微信小程序实现slideUp、slideDown滑动效果及点击空白隐藏功能示例
Dec 11 Javascript
JS实现checkbox互斥(单选)功能示例
May 04 Javascript
浅谈JS中几种轻松处理'this'指向方式
Sep 16 Javascript
Vue+ElementUI使用vue-pdf实现预览功能
Nov 26 Javascript
使用JavaScript通过前端发送电子邮件
May 22 Javascript
js关闭父窗口时关闭子窗口
Apr 01 #Javascript
基于jQuery实现模拟页面加载进度条
Apr 01 #Javascript
javascript ie6兼容position:fixed实现思路
Apr 01 #Javascript
JavaScript中的onerror事件概述及使用
Apr 01 #Javascript
js捕获鼠标右键菜单中的粘帖事件实现代码
Apr 01 #Javascript
向当前style sheet中插入一个新的style实现方法
Apr 01 #Javascript
select标签模拟/美化方法采用JS外挂式插件
Apr 01 #Javascript
You might like
使用PHP数组实现无限分类,不使用数据库,不使用递归.
2006/12/09 PHP
php使用Jpgraph绘制柱形图的方法
2015/06/10 PHP
在WordPress中获取数据库字段内容和添加主题设置菜单
2016/01/11 PHP
PHP时间戳格式全部汇总 (获取时间、时间戳)
2016/06/13 PHP
jquery 利用show和hidden实现级联菜单示例代码
2013/08/09 Javascript
Firefox和IE兼容性问题及解决方法总结
2013/10/08 Javascript
JS记录用户登录次数实现代码
2014/01/15 Javascript
javascript校验价格合法性实例(必须输入2位小数)
2014/05/05 Javascript
JavaScript实现按Ctrl键打开新页面
2014/09/04 Javascript
分享一则JavaScript滚动条插件源码
2015/03/03 Javascript
JavaScript按值删除数组元素的方法
2015/04/24 Javascript
前端把html表格生成为excel表格的实例
2017/09/19 Javascript
Bootstrap table表格初始化表格数据的方法
2018/07/25 Javascript
Javascript中parseInt的正确使用方式
2018/10/17 Javascript
VUE+node(express)实现前后端分离
2019/10/13 Javascript
Vue在H5 项目中使用融云进行实时个人单聊通讯
2020/12/14 Vue.js
Vue ​v-model相关知识总结
2021/01/28 Vue.js
Python书单 不将就
2017/07/11 Python
python爬虫之xpath的基本使用详解
2018/04/18 Python
python检索特定内容的文本文件实例
2018/06/05 Python
简单介绍python封装的基本知识
2019/08/10 Python
Python如何实现爬取B站视频
2020/05/20 Python
为什么说python更适合树莓派编程
2020/07/20 Python
浅谈对python中if、elif、else的误解
2020/08/20 Python
Python之qq自动发消息的示例代码
2021/02/18 Python
英国领先的男装设计师服装购物网站:Mainline Menswear
2018/02/04 全球购物
爱普生美国官网:Epson美国
2018/11/05 全球购物
Etam德国:内衣精品店
2019/08/25 全球购物
欧洲最古老的鞋厂:Peter Kaiser
2019/11/05 全球购物
PyQt QMainWindow的使用示例
2021/03/24 Python
千元咖啡店的创业计划书范文
2013/12/29 职场文书
税务干部个人整改措施思想汇报
2014/10/10 职场文书
2015年中学元旦晚会活动方案
2014/12/09 职场文书
2017大学生寒假社会实践心得体会
2016/01/14 职场文书
浅谈Golang 嵌套 interface 的赋值问题
2021/04/29 Golang
SpringMVC 整合SSM框架详解
2021/08/30 Java/Android