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中的其他对象
Jan 16 Javascript
Extjs Ext.MessageBox.confirm 确认对话框详解
Apr 02 Javascript
jquery控制左右箭头滚动图片列表的实例
May 20 Javascript
原始的js代码和jquery对比体会
Sep 10 Javascript
JavaScript 判断用户输入的邮箱及手机格式是否正确
Dec 08 Javascript
php和js对数据库图片进行等比缩放示例
Apr 28 Javascript
调整小数的格式保留小数点后两位
May 14 Javascript
ztree加载完成后显示勾选节点的实现代码
Oct 22 Javascript
js中innerText/textContent和innerHTML与target和currentTarget的区别
Jan 21 Javascript
Vue 实例事件简单示例
Sep 19 Javascript
JavaScript进阶(四)原型与原型链用法实例分析
May 09 Javascript
vant-ui AddressEdit地址编辑和van-area的用法说明
Nov 03 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
ThinkPHP公共配置文件与各自项目中配置文件组合的方法
2014/11/24 PHP
php封装好的人民币数值转中文大写类
2015/12/20 PHP
PHP Static延迟静态绑定用法分析
2016/03/16 PHP
thinkphp ajaxfileupload实现异步上传图片的示例
2017/08/28 PHP
Laravel框架实现多数据库连接操作详解
2019/07/12 PHP
jQuery 跨域访问问题解决方法
2009/12/02 Javascript
jquery 读取页面load get post ajax 四种方式代码写法
2011/04/02 Javascript
script的async属性以非阻塞的模式加载脚本
2013/01/15 Javascript
js返回上一页并刷新的多种实现方法
2014/02/26 Javascript
js实现索引图片切换效果
2015/11/21 Javascript
让你一句话理解闭包(简单易懂)
2016/06/03 Javascript
基于JavaScript代码实现自动生成表格
2016/06/15 Javascript
漫谈JS引擎的运行机制 你应该知道什么
2016/06/15 Javascript
jQuery Ztree行政地区树状展示(点击加载)
2016/11/09 Javascript
Bootstrap中data-target 到底是什么
2017/02/14 Javascript
Layui组件Table绑定行点击事件和获取行数据的方法
2018/08/19 Javascript
JavaScript基于遍历操作实现对象深拷贝功能示例
2019/03/05 Javascript
JS实现提示框跟随鼠标移动
2019/08/27 Javascript
vue-resource post数据时碰到Django csrf问题的解决
2020/03/13 Javascript
修改Vue打包后的默认文件名操作
2020/08/12 Javascript
如何通过JS实现日历简单算法
2020/10/14 Javascript
Python解释执行原理分析
2014/08/22 Python
Python使用PIL库实现验证码图片的方法
2016/03/11 Python
对pandas数据判断是否为NaN值的方法详解
2018/11/06 Python
Python检查 云备份进程是否正常运行代码实例
2019/08/22 Python
python时间序列数据转为timestamp格式的方法
2020/08/03 Python
PyCharm Ctrl+Shift+F 失灵的简单有效解决操作
2021/01/15 Python
一款超酷的js+css3实现的3D标签云特效兼容ie7/8/9
2013/11/18 HTML / CSS
Lime Crime官网:美国一家主打梦幻精灵系的彩妆品牌
2019/03/22 全球购物
员工自我鉴定范文
2013/10/06 职场文书
消防宣传口号
2014/06/16 职场文书
2014第二批党员干部对照“四风”找差距检查材料思想汇报
2014/09/18 职场文书
授权收款委托书
2014/09/23 职场文书
2015年社区矫正工作总结
2015/04/21 职场文书
php将xml转化对象的实例详解
2021/11/17 PHP
分享一个vue实现的记事本功能案例
2022/04/11 Vue.js