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


Posted in Javascript onNovember 17, 2015

首先通过一个例子来回顾一下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>

然后效果一般时这样的:

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

美与丑暂且不论...所有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);

运行代码跟原来的不变。

Javascript 相关文章推荐
执行iframe中的javascript方法
Oct 07 Javascript
javascript获取ckeditor编辑器的值(实现代码)
Nov 18 Javascript
javascript 获取网页标题代码实例
Jan 22 Javascript
js实现宇宙星空背景效果的方法
Mar 03 Javascript
JQuery中层次选择器用法实例详解
May 18 Javascript
jquery实现列表上下移动功能
Feb 25 Javascript
移动端横屏的JS代码(beta)
May 16 Javascript
JS组件系列之JS组件封装过程详解
Apr 28 Javascript
AngularJS中重新加载当前路由页面的方法
Mar 09 Javascript
element UI upload组件上传附件格式限制方法
Sep 04 Javascript
JavaScript如何实现元素全排列实例代码
May 14 Javascript
ES6学习教程之Promise用法详解
Nov 22 Javascript
基于Jquery easyui 选中特定的tab
Nov 17 #Javascript
jquery实现简单的表单验证
Nov 17 #Javascript
将JavaScript的jQuery库中表单转化为JSON对象的方法
Nov 17 #Javascript
基于jquery实现可定制的web在线富文本编辑器附源码下载
Nov 17 #Javascript
Jquery ajax 同步阻塞引起的UI线程阻塞问题
Nov 17 #Javascript
jquery判断密码强度的验证代码
Apr 22 #Javascript
jquery实现邮箱自动填充提示功能
Nov 17 #Javascript
You might like
PHP 选项及相关信息函数库
2006/12/04 PHP
php如何调用webservice应用介绍
2012/11/24 PHP
php跨站攻击实例分析
2014/10/28 PHP
PHP实现的简单缓存类
2015/07/29 PHP
Thinkphp框架 表单自动验证登录注册 ajax自动验证登录注册
2016/12/27 PHP
jQuery实现的类flash菜单效果代码
2010/05/17 Javascript
js获取url中指定参数值的示例代码
2013/12/14 Javascript
jQuery选择器简明总结(含用法实例,一目了然)
2014/04/25 Javascript
JavaScript中用字面量创建对象介绍
2014/12/31 Javascript
简介JavaScript中Boolean.toSource()方法的使用
2015/06/05 Javascript
浅谈window对象的scrollBy()方法
2015/07/15 Javascript
基于ajax实现文件上传并显示进度条
2015/08/03 Javascript
关于Function中的bind()示例详解
2016/12/02 Javascript
canvas实现图片根据滑块放大缩小效果
2017/02/24 Javascript
微信小程序 MD5的方法详解及实例代码
2017/03/10 Javascript
修改 bootstrap table 默认detailRow样式的实例代码
2017/07/21 Javascript
利用百度地图API获取当前位置信息的实例
2017/11/06 Javascript
webpack4+express+mongodb+vue实现增删改查的示例
2018/11/08 Javascript
Python 结巴分词实现关键词抽取分析
2017/10/21 Python
浅谈Python中带_的变量或函数命名
2017/12/04 Python
Python实现简单生成验证码功能【基于random模块】
2018/02/10 Python
Python 使用PIL numpy 实现拼接图片的示例
2018/05/08 Python
python 获取url中的参数列表实例
2018/12/18 Python
Python通过paramiko远程下载Linux服务器上的文件实例
2018/12/27 Python
python对指定字符串逆序的6种方法(小结)
2020/04/02 Python
python上传时包含boundary时的解决方法
2020/04/08 Python
Python openpyxl模块实现excel读写操作
2020/06/30 Python
苹果美国官方商城:Apple美国
2016/08/24 全球购物
毕业生精彩的自我评价分享
2013/10/06 职场文书
前厅收银主管岗位职责
2014/02/04 职场文书
宾馆总经理岗位职责
2014/02/14 职场文书
天猫某品牌专卖店运营计划书
2014/03/21 职场文书
《广玉兰》教学反思
2014/04/14 职场文书
教师“一帮一”结对子活动总结
2015/05/07 职场文书
redis配置文件中常用配置详解
2021/04/14 Redis
Python加密技术之RSA加密解密的实现
2022/04/08 Python