用JavaScript来美化HTML的select标签的下拉列表效果

首先通过一个例子来回顾一下select标签的用法:

<html>

<body>

<form>
<select name="cars">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="fiat">Fiat</option>
<option value="audi">Audi</option>
</select>
</form>

</body>
</html>

然后效果一般时这样的:

20151117144635327.png (119×118)

美与丑暂且不论...所有html元素中select算是比较坑爹的一个。他让人抓狂的地方主要是:
 
不同的浏览器显示的默认下拉框样子不完全相同
IE下无法手动设置select的高度(这是最坑爹的!),只能靠font-size撑起来
select右侧的下拉箭头是无法使用背景消除的,这就导致无法使用css进行美化
总结起来,解决办法主要有:

将select隐藏掉,而使用div进行模拟
将select透明度设置为0,然后使用相对定位在下方 加一个长得很像select又美化了的div

隐藏方案一般原理如下:
找到页面需要处理的select,将其隐藏
根据select的option,创建一个li列表(当然也可以是div),并隐藏。
在select的位置创建一个div,显示select的值(selected的option)。并使用css对其进行美化,使其看起来像一个select
添加事件,使点击“select”的时候,显示li列表。并使用相对定位,让这个列表显示在“select”下方
对li列表添加事件,模拟下拉框的选值过程(点击事件和键盘↑↓事件都要模拟)
选值完成后,要将选的值显示到上方的“select”,并设置真正的select的值
当然,如果你想做的更复杂点,还可以添加选项搜索、多选、多选后的选项删除等。当时一般原理都跟上面差不多。网上也有很多这样的插件。但使用网上的插件要注意测试浏览器的兼容性,功能越复杂的模拟select,兼容性越不好做
 
如果,你的程序不需要那么复杂的select,那么设置透明度的第二种方案也许适合你。今天要分享给大家的也是这个方案。
它的原理如下:
 
 
找到当前页面的select,将其透明度设置为0.使其看不见,但是可以点击并选值
创建一个div,使用相对定位,放置到select下方 ,并通过css控制使其看起来像一个select。为什么一定要放在下方呢?因为这样,我们可以点击真正的select,而用户看起来像是点击的这个模拟的select,因为真正的select是完全透明的。如果放置在上方,则用户点击的是这个模拟的select,真正的select不会展开!!!
设置div的text为select的值
添加事件,使真正的select选值后,将值显示到模拟的div上
 
 
先上代码吧:
 

( function ($){
var selectFix= function (){
var select=$( this );
//设置透明度为0 当然你也可以使用css控制 使用Jquery设置透明度可以屏蔽 透明度的 浏览器兼容性问题
$(select).css({
"opacity" :0
});
//找到select的选项
var sOptions= this .get(0).options;
//设置模拟select的值
var setFixDivText= function (selectValue){
var text= "" ;
for ( var i=0;i<sOptions.length;i++){
var option=sOptions[i];
if (option.value==selectValue){
text=$(option).text();
break ;
}
}
return text;
};
//模拟的select
//初始化时要将select的值传入
var selectFixDiv=$( '<div id="J_selectFix_' +select.attr("id ")+'" class = "selectFix" >'+setFixDivText($(select).val())+ '</div>' );
select.after(selectFixDiv);
var left=$(select).offset().left;
var top=$(select).offset().top-1; //因为一般select都有1px的边框,所以这里往上拉1px
$(selectFixDiv).css({
"top" : top,
"left" : left
});
//select选值时,将值显示到模拟的select上
$(select).bind( "change click" , function (){
$(selectFixDiv).text(setFixDivText($( this ).val()));
});
};
$.fn.selectFix=selectFix;
})(jQuery);
(function($){ 
  var selectFix=function(){ 
    var select=$(this); 
    //设置透明度为0 当然你也可以使用css控制 使用Jquery设置透明度可以屏蔽 透明度的 浏览器兼容性问题 
    $(select).css({ 
      "opacity":0 
    }); 
    //找到select的选项 
    var sOptions=this.get(0).options; 
    //设置模拟select的值 
    var setFixDivText=function(selectValue){ 
      var text=""; 
      for(var i=0;i<sOptions.length;i++){ 
        var option=sOptions[i]; 
        if(option.value==selectValue){ 
          text=$(option).text(); 
          break; 
        } 
      } 
      return text; 
    }; 
 
    //模拟的select 
    //初始化时要将select的值传入 
    var selectFixDiv=$('<div id="J_selectFix_'+select.attr("id")+'" class="selectFix">'+setFixDivText($(select).val())+'</div>'); 
    select.after(selectFixDiv); 
 
    var left=$(select).offset().left; 
    var top=$(select).offset().top-1;//因为一般select都有1px的边框,所以这里往上拉1px 
    $(selectFixDiv).css({ 
      "top" : top, 
      "left" : left 
    }); 
     
    //select选值时,将值显示到模拟的select上 
    $(select).bind("change click",function(){ 
      $(selectFixDiv).text(setFixDivText($(this).val())); 
    }); 
  }; 
  $.fn.selectFix=selectFix; 
})(jQuery); 

 
 
插件代码运行:
 

jQuery(document).ready( function () {
var selects=$( "select.selectInput" );
if (selects.length){
selects.each( function (){
$( this ).selectFix();
});
}
});

jQuery(document).ready(function() { 
  var selects=$("select.selectInput"); 
  if(selects.length){ 
    selects.each(function(){ 
      $(this).selectFix(); 
    }); 
  } 
}); 

下面是html代码:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
< HTML >
< HEAD >
< TITLE > New Document </ TITLE >
< META NAME = "Generator" CONTENT = "EditPlus" >
< META NAME = "Author" CONTENT = "" >
< META NAME = "Keywords" CONTENT = "" >
< META NAME = "Description" CONTENT = "" >
< script type = text /javascript src = "http://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js" > </ script >
< script type = text /javascript src = "temp.js" > </ script >
< style >
html {font-family: "宋体";font-size: 12px;line-height: 25px;color: #6F6F6F;}
.dn {display: none;}
select{cursor: pointer;}
input,
select,
textarea,
.selectFix {background: white;border: 1px solid #E0E0E0;hide-focus: expression( this.hideFocus = true ); outline: none;}
.formText,
.selectInput,
.text,
.selectFix{border: 1px solid #CCC;width: 180px;height: 30px;line-height:30px;padding: 0 3px;}
.selectInput {width: 248px; font-size:13px; position: relative; z-index: 2;}
.selectFix{width:248px; background: url(selectBg.png) no-repeat; background-position: right; background-color: #fff; position:absolute; z-index: 1;}
</ style >
</ HEAD >
< BODY >
< div id = "main" >
< select id = "sex" class = "selectInput" name = "sex" >
< option value = "0" > 男 </ option >
< option value = "1" > 女 </ option >
</ select >
</ div >
</ BODY >
</ HTML >

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> 
<HTML> 
<HEAD> 
<TITLE> New Document </TITLE> 
<META NAME="Generator" CONTENT="EditPlus"> 
<META NAME="Author" CONTENT=""> 
<META NAME="Keywords" CONTENT=""> 
<META NAME="Description" CONTENT=""> 
 <script type=text/javascript src="http://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js"></script> 
 <script type=text/javascript src="temp.js"></script> 
 
 <style> 
html {font-family: "宋体";font-size: 12px;line-height: 25px;color: #6F6F6F;} 
.dn {display: none;} 
select{cursor: pointer;} 
input, 
select, 
textarea, 
.selectFix {background: white;border: 1px solid #E0E0E0;hide-focus: expression(this.hideFocus=true); outline: none;} 
.formText, 
.selectInput, 
.text, 
.selectFix{border: 1px solid #CCC;width: 180px;height: 30px;line-height:30px;padding: 0 3px;} 
.selectInput {width: 248px; font-size:13px; position: relative; z-index: 2;} 
.selectFix{width:248px; background: url(selectBg.png) no-repeat; background-position: right; background-color: #fff; position:absolute; z-index: 1;} 
 </style> 
</HEAD> 
 
<BODY> 
<div id="main"> 
  <select id="sex" class="selectInput" name="sex"> 
    <option value="0">男</option> 
    <option value="1">女</option> 
  </select> 
</div> 
</BODY> 
</HTML> 

兼容主流浏览器。
 
 
但也还是有个重大的缺陷,在老版本的ie中,真正select的高度还是无法撑开。所以,用户点击模拟的select的靠下方的位置会发现select无法展开!!
不过设计的艺术在于平衡,如果你无法忍受这个缺陷,可以使用第一种解决方案。
 
 
另外,在测试后,发现如果select处于一个隐藏的容器中,那么显示后,select的位置是一个空白!!
这是怎么回事呢?!
原来,html元素隐藏后是无法获取他的屏幕坐标的!!! 所以这时候显示出来,真正的select完全透明了,而模拟的select跑到屏幕的左上角去了。因为他获取select的坐标为(0,0)
 
 
不要着急,这个问题有下面的解决办法:
1、单独写代码触发select的美化程序
首先,你需要将上面的美化程序运行代码做以下修改:
 

jQuery(document).ready( function () {
var selects=$( "select.selectInput" );
if (selects.length){
selects.each( function (){
if (!($( this ).attr( "autoFix" )== "false" )){
$( this ).selectFix();
}
});
}
});

jQuery(document).ready(function() { 
  var selects=$("select.selectInput"); 
  if(selects.length){ 
    selects.each(function(){ 
      if(!($(this).attr("autoFix")=="false")){ 
        $(this).selectFix(); 
      } 
    }); 
  } 
}); 

然后,在隐藏的select上加属性autoFix="false":

< select id = "sex" class = "selectInput" name = "sex" autoFix = "false" >
< option value = "0" > 男 </ option >
< option value = "1" > 女 </ option >
</ select >

<select id="sex" class="selectInput" name="sex" autoFix="false"> 
    <option value="0">男</option> 
    <option value="1">女</option> 
  </select> 

然后,在外部容器显示的时候,手动调用$("#sex").selectFix()
 
2、如果容器的显示或者隐藏是第三方插件控制,修改不方便可考虑下面的方案:
在美化程序中,先判断select是否隐藏,如果否逻辑不变,如果隐藏,则加入一个timer,循环判断元素是否被显示,在其显示的时候再自动调用fix,然后将timer移除
代码如下:
 

//加上隐藏select的操作
( function ($){
var selectFix= function (){
var select=$( this );
//设置透明度为0 当然你也可以使用css控制 使用Jquery设置透明度可以屏蔽 透明度的 浏览器兼容性问题
$(select).css({
"opacity" :0
});
if (!select.is( ":hidden" )){
var sOptions= this .get(0).options;
var setFixDivText= function (selectValue){
var text= "" ;
for ( var i=0;i<sOptions.length;i++){
var option=sOptions[i];
if (option.value==selectValue){
text=$(option).text();
break ;
}
}
return text;
};
var selectFixDiv=$( '<div id="J_selectFix_' +select.attr("id ")+'" class = "selectFix" status= "close" >'+setFixDivText($(select).val())+ '</div>' );
select.after(selectFixDiv);
var selectWidth=$(select).innerWidth();
var selectFixDivWidth=$(selectFixDiv).innerWidth();
var left=$(select).offset().left;
var top=$(select).offset().top-1;
$(selectFixDiv).css({
"top" : top,
"left" : left,
"margin" : 0
});
$(select).bind( "change click" , function (){
$(selectFixDiv).text(setFixDivText($( this ).val()));
});
} else {
var tasks = function (){
if (!$(select).is( ":hidden" )){
$(select).selectFix();
clearInterval(timer);
}
};
var timer=setInterval(tasks,500)
}
};
$.fn.selectFix=selectFix;
})(jQuery);
//加上隐藏select的操作 
(function($){ 
  var selectFix=function(){ 
    var select=$(this); 
    //设置透明度为0 当然你也可以使用css控制 使用Jquery设置透明度可以屏蔽 透明度的 浏览器兼容性问题 
    $(select).css({ 
      "opacity":0 
    }); 
 
    if(!select.is(":hidden")){ 
      var sOptions=this.get(0).options; 
 
      var setFixDivText=function(selectValue){ 
        var text=""; 
        for(var i=0;i<sOptions.length;i++){ 
          var option=sOptions[i]; 
          if(option.value==selectValue){ 
            text=$(option).text(); 
            break; 
          } 
        } 
        return text; 
      }; 
 
      var selectFixDiv=$('<div id="J_selectFix_'+select.attr("id")+'" class="selectFix" status="close">'+setFixDivText($(select).val())+'</div>'); 
      select.after(selectFixDiv); 
 
      var selectWidth=$(select).innerWidth(); 
      var selectFixDivWidth=$(selectFixDiv).innerWidth(); 
      var left=$(select).offset().left; 
 
      var top=$(select).offset().top-1; 
      $(selectFixDiv).css({ 
        "top" : top, 
        "left" : left, 
        "margin" : 0 
      }); 
 
      $(select).bind("change click",function(){ 
        $(selectFixDiv).text(setFixDivText($(this).val())); 
      }); 
    }else{ 
      var tasks = function(){ 
        if(!$(select).is(":hidden")){ 
          $(select).selectFix(); 
          clearInterval(timer); 
        } 
      }; 
      var timer=setInterval(tasks,500) 
    } 
  }; 
  $.fn.selectFix=selectFix; 
})(jQuery); 

运行代码跟原来的不变。

本页内容版权归属为原作者,如有侵犯您的权益,请通知我们删除。
1.语法及返回方式 ①返回控制与函数结果 语法为:return 表达式; 语句结果函数的执行,返回调用函数,而且把表达式的值作为函数结果返回出去 ②返回控制无函数结果 语法为:return; 在大多数情况下,为事件处理函数如果让其返回false,可以防止默认的事件行为.例如,默认情况下,点击一个a标签元素,页面会跳转到该元素href属性指定的页. 而return false就相当于终止符,return true就相当于执行符. 在js中return false的作用一般是用来取消默认动作的.比如你单击一个

js全选按钮的实现方法 - 2015-11-19 19:11:45

本文实例讲述了js全选按钮的实现代码。分享给大家供大家参考。具体如下: 运行效果截图如下: 具体代码如下 html head title复选框checked属性/title script language="JavaScript" type="text/javascript" function changeState(isChecked) { var chk_list=document.getElementsByTagName("input"); for(var i=0;ichk_list.length;
最近做一个项目,遇到了一个问题同步ajax引起的ui线程阻塞问题,下面把我的问题解决过程分享给大家。 事情起因是这样的,因为页面上有多个相似的异步请求动作,本着提高代码可重用性的原则,我封装了一个名为getData的函数,它接收不同参数,只负责获取数据,然后把数据return。基本的逻辑剥离出来是这样的: function getData1(){ var result; $.ajax({ url : "p.php", async : false, success: function(data){ resu
分享一款支持PC端手机端幻灯片代码是一款支持移动触摸,支持鼠标拖拽切换,支持带进度条的自动播放模式。交果图如下 : 效果演示 源码下载 html代码: div class="flex" ul class="slides" li data-title="Slide 1" img alt="" src="img/beasts_feature.jpg" /li li data-title="Slide 2" img alt="" src="img/element-taiwan-thmb.jpg" /li li
废话不多说了,直接给大家贴代码了。 具体代码如下: var CookieUtil = (function () { var Cookie = function () { // 获取单值cookie this.get = function(name) { var start = document.cookie.indexOf(encodeURIComponent(name)) ; var end = document.cookie.indexOf(';', start) ; if(end == -) { e
本文实例讲述了jquery判断密码强度的验证代码,分享给大家供大家参考。具体如下: 预想的效果截图如下: JS代码: $('#pass').keyup(function(e) { var strongRegex = new RegExp("^(?=.{8,})(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*\\W).*$", "g"); var mediumRegex = new RegExp("^(?=.{7,})(((?=.*[A-Z])(?=.*[a-z]))|((?=.

Jquery easyui 实现动态树 - 2015-11-19 18:11:15

在上篇文章给大家介绍了 jquery中EasyUI实现异步树 ,本文给大家介绍jquery easyui实现动态树。 首先是在jsp页面中引入相关的js文件 在body中加入流程列表,通过后天拼接json数据 具体内容请看下面代码详情吧。 首选在jsp页面中引入相关的js link rel="stylesheet" type="text/css" href=#> 添加script script $(function(){ $('#tt2').tree({ checkbox: false, url: '%=

jquery实现简单的表单验证 - 2015-11-19 18:11:15

jquery如何实现简单的表单验证,我们先跟大家分享一下实现思路。 大概思路: 先为每一个required添加必填的标记,用 each() 方法来实现。 在each()方法中先是 创建一个元素, 然后通过 append()方法 将创建的元素加入到父元素后面。 这里面的 this 用的很精髓,每一次的this都对应着相应的input元素,然后获取相应的父元素。 然后为 input 元素添加失去焦点事件。然后进行用户名、邮件的验证。 这里用了一个 判断is() , 如果是用户名,做相应的处理,如果是邮件做相应
邮箱的广泛使用得益于它的免费,因此很多网站在注册的时候都会直接使用邮箱作为账号名 为了提高用户的体验,很多网站都会实现邮箱输入的自动提示功能,所有自己也实现了一个,先看下效果吧,觉得效果还行的就拿去 核心代码(需要jquery的支持): (function($){ $.fn.mailAutoComplete = function(options){ var defaults = { boxClass: "mailListBox", //外部box样式 listClass: "mailListDefault
1、正则仅仅就是用来处理字符串的:匹配、捕获 匹配:验证当前的字符串是否符合我们的规则(每一个正则都是一个规则) 捕获:在整个字符串当中,把符合规则的字符都依次的获取到---exec、match、replace 2、正则的组成:元字符、修饰符 元字符: 特殊意义的元字符: \d匹配一个0-9的数字相当于[0-9],和它相反的 \D匹配一个除了0-9的任意字符相当于【】 \w匹配一个0-9、a-z、A-Z_ 的数字或字符,相当于[0-9a-zA-Z_] 、 \s匹配一个空白字符(空格、制表符。。。) \b匹