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 相关文章推荐
页面版文本框智能提示JS代码
Nov 20 Javascript
javascript 模拟点击广告
Jan 02 Javascript
jQuery学习7 操作JavaScript对象和集合的函数
Feb 07 Javascript
javascript 隔行换色函数代码
Oct 24 Javascript
jQuery 删除或是清空某个HTML元素示例
Aug 04 Javascript
JavaScript 学习笔记之数据类型
Jan 14 Javascript
JS仿iGoogle自定义首页模块拖拽特效的方法
Feb 13 Javascript
javascript实现链接单选效果的方法
May 13 Javascript
原生JavaScript制作微博发布面板效果
Mar 11 Javascript
JavaScript兼容性总结之获取非行间样式案例
Aug 07 Javascript
深入理解Angularjs中$http.post与$.post
May 19 Javascript
超详细的5个Shell脚本实例分享(值得收藏)
Aug 15 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提交post数组参数实例分析
2015/12/17 PHP
ThinkPHP和UCenter接口冲突的解决方法
2016/07/25 PHP
PHP性能测试工具xhprof安装与使用方法详解
2018/04/29 PHP
php使用yield对性能提升的测试实例分析
2019/09/19 PHP
Javascript实现仿WebQQ界面的“浮云”兼容 IE7以上版本及FF
2011/04/27 Javascript
js 删除数组的几种方法小结
2014/02/21 Javascript
jQuery的选择器中的通配符使用介绍
2014/03/20 Javascript
Jquery实现由下向上展开效果的例子
2014/12/08 Javascript
Javascript之Math对象详解
2016/06/07 Javascript
JavaScript的变量声明提升问题浅析(Hoisting)
2016/11/30 Javascript
微信小程序 Template详解及简单实例
2017/01/05 Javascript
微信小程序 MD5的方法详解及实例代码
2017/03/10 Javascript
优化Vue项目编译文件大小的方法步骤
2019/05/27 Javascript
jQuery实现移动端图片上传预览组件的方法分析
2020/05/01 jQuery
javascript实现文字跑马灯效果
2020/06/18 Javascript
[03:16]DOTA2完美大师赛主赛事首日集锦
2017/11/23 DOTA
python共享引用(多个变量引用)示例代码
2013/12/04 Python
python中对list去重的多种方法
2014/09/18 Python
python随机生成指定长度密码的方法
2015/04/04 Python
Python实现图片尺寸缩放脚本
2018/03/10 Python
python3.6利用pyinstall打包py为exe的操作实例
2018/10/31 Python
python利用Tesseract识别验证码的方法示例
2019/01/21 Python
如何基于python3和Vue实现AES数据加密
2020/03/27 Python
基于python检查SSL证书到期情况代码实例
2020/04/04 Python
django使用graphql的实例
2020/09/02 Python
Lookfantastic日本官网:英国知名护肤、化妆品和头发护理购物网站
2018/04/21 全球购物
美国最好的钓鱼、狩猎和划船装备商店:Bass Pro Shops
2018/12/02 全球购物
Pandora西班牙官方商店:PandoraShop.es
2020/10/05 全球购物
家长通知书教师评语
2014/04/17 职场文书
考研复习计划
2015/01/19 职场文书
苏州园林导游词
2015/02/03 职场文书
2015年国庆节慰问信
2015/03/23 职场文书
教师读书活动心得体会
2016/01/14 职场文书
家庭教育教师培训学习体会
2016/01/14 职场文书
2019大学毕业晚会主持词
2019/06/21 职场文书
JS开发前端团队展示控制器来为成员引流
2022/08/14 Javascript