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 相关文章推荐
使用TextRange获取输入框中光标的位
Oct 14 Javascript
onbeforeunload与onunload事件异同点总结
Jun 24 Javascript
jQuery - css() 方法示例详解
Jan 16 Javascript
JS实现很酷的水波文字特效实例
Feb 26 Javascript
浅谈JavaScript的事件
Feb 27 Javascript
JavaScript在Android的WebView中parseInt函数转换不正确问题解决方法
Apr 25 Javascript
jQuery插件实现多级联动菜单效果
Dec 01 Javascript
原生javascript实现分享到朋友圈功能 支持ios和android
May 11 Javascript
javascript表达式和运算符详解
Feb 07 Javascript
详解Angular如何正确的操作DOM
Jul 06 Javascript
jQuery使用bind动态绑定事件无效的处理方法
Dec 11 jQuery
安装多版本Vue-CLI的实现方法
Mar 24 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的慢速日志引起的Mysql错误问题分析
2014/05/13 PHP
PHP中使用CURL模拟登录并获取数据实例
2014/07/01 PHP
浅谈PHP中output_buffering
2015/07/13 PHP
Symfony2学习笔记之模板用法详解
2016/03/17 PHP
PHP递归遍历文件夹去除注释并压缩php源代码的方法示例
2018/05/23 PHP
PHP消息队列实现及应用详解【队列处理订单系统和配送系统】
2019/05/20 PHP
laravel 解决后端无法获取到前端Post过来的值问题
2019/10/22 PHP
JavaScript中为元素加上name属性的方法
2011/05/09 Javascript
window.open 以post方式传递参数示例代码
2014/02/27 Javascript
jQuery实现带有洗牌效果的动画分页实例
2015/08/31 Javascript
以JavaScript来实现WordPress中的二级导航菜单的方法
2015/12/14 Javascript
jquery拖拽效果完整实例(附demo源码下载)
2016/01/14 Javascript
jQuery.deferred对象使用详解
2016/03/18 Javascript
jquery 点击元素后,滚动条滚动至该元素位置的方法
2016/08/05 Javascript
vue-router实现webApp切换页面动画效果代码
2017/05/25 Javascript
Angular客户端请求Rest服务跨域问题的解决方法
2017/09/19 Javascript
SeaJS中use函数用法实例分析
2017/10/10 Javascript
vue封装一个简单的div框选时间的组件的方法
2019/01/06 Javascript
vue.js实现数据库的JSON数据输出渲染到html页面功能示例
2019/08/03 Javascript
浅谈vue-router路由切换 组件重用挖下的坑
2019/11/01 Javascript
linux 下以二进制的方式安装 nodejs
2020/02/12 NodeJs
Python中for循环控制语句用法实例
2015/06/02 Python
Python3使用正则表达式爬取内涵段子示例
2018/04/22 Python
详解python使用turtle库来画一朵花
2019/03/21 Python
Python的几种主动结束程序方式
2019/11/22 Python
PyCharm最新激活码PyCharm2020.2.3有效
2020/11/18 Python
解决pytorch下出现multi-target not supported at的一种可能原因
2021/02/06 Python
使用html5+css3来实现slider切换效果告别javascript+css
2013/01/08 HTML / CSS
迪卡侬印尼体育用品商店:Decathlon印尼
2020/03/11 全球购物
优秀德育工作者事迹材料
2014/05/07 职场文书
遵纪守法演讲稿
2014/05/23 职场文书
委托书怎么写
2014/07/31 职场文书
群众路线个人剖析材料
2014/10/07 职场文书
2014年安全员工作总结
2014/11/13 职场文书
办公室年度工作总结2015
2015/05/21 职场文书
详解MySQL数据库千万级数据查询和存储
2021/05/18 MySQL