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入门·对象属性方法大总结
Oct 01 Javascript
JavaScript 常用函数
Dec 30 Javascript
JavaScript入门之事件、cookie、定时等
Oct 21 Javascript
js去除重复字符串两种实现方法
Jan 09 Javascript
js 时间函数应用加、减、比较、格式转换的示例代码
Aug 23 Javascript
js将json格式内容转换成对象的方法
Nov 01 Javascript
js实现点击获取验证码倒计时效果
Jan 28 Javascript
javascript 继承学习心得总结
Mar 17 Javascript
浅谈JS中的bind方法与函数柯里化
Aug 10 Javascript
JS变量及其作用域
Mar 29 Javascript
vue与vue-i18n结合实现后台数据的多语言切换方法
Mar 08 Javascript
uni-app使用countdown插件实现倒计时
Nov 01 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 读取文件乱码问题
2010/02/20 PHP
Laravel最佳分割路由文件(routes.php)的方式
2016/08/04 PHP
PHP批斗大会之缺失的异常详解
2019/07/09 PHP
JavaScript面向对象之体会[总结]
2008/11/13 Javascript
JavaScript中的replace()方法使用详解
2015/06/06 Javascript
JavaScript编程学习技巧汇总
2016/02/21 Javascript
JavaScript实现多栏目切换效果
2016/12/12 Javascript
集合Bootstrap自定义confirm提示效果
2017/09/19 Javascript
一秒学会微信小程序制作table表格
2019/02/14 Javascript
详解React项目中碰到的IE问题
2019/03/14 Javascript
nuxt配置通过指定IP和端口访问的实现
2020/01/08 Javascript
javaScript 实现重复输出给定的字符串的常用方法小结
2020/02/20 Javascript
[07:59]2014DOTA2叨叨刀塔 林熊猫称被邀请赛现场盛况震撼
2014/07/21 DOTA
[01:08]DOTA2“血战之命”预告片
2017/08/12 DOTA
[00:10]DOTA2全国高校联赛 以DOTA2会友
2018/05/30 DOTA
Python及PyCharm下载与安装教程
2017/11/18 Python
Python3中exp()函数用法分析
2019/02/19 Python
python实现银行管理系统
2019/10/25 Python
Ubuntu16.04安装python3.6.5步骤详解
2020/01/10 Python
Python基于callable函数检测对象是否可被调用
2020/10/16 Python
python中altair可视化库实例用法
2021/01/26 Python
python+selenium爬取微博热搜存入Mysql的实现方法
2021/01/27 Python
CSS3 伪类选择器 nth-child()说明
2010/07/10 HTML / CSS
解决HTML5手机端页面缩放的问题
2017/10/27 HTML / CSS
REISS英国官网:伦敦High Street最受欢迎品牌
2016/12/21 全球购物
下面代码从性能上考虑,有什么问题
2015/04/03 面试题
日期和时间问题
2015/01/04 面试题
什么是封装
2013/03/26 面试题
高中生的自我鉴定范文
2014/01/24 职场文书
火车来了教学反思
2014/02/11 职场文书
三好生演讲稿
2014/09/12 职场文书
护士辞职信怎么写
2015/02/27 职场文书
小学生安全教育主题班会
2015/08/12 职场文书
2016年党员学习廉政准则心得体会
2016/01/20 职场文书
详解Python牛顿插值法
2021/05/11 Python
继承Win10缺点!教你关闭Win11烦人的网络搜索
2021/11/23 数码科技