javascript实现下拉框表单美化的详细实例教程

html的表单有很强大的功能,在web早期的时候,表单是页面向服务器发起通信的主要渠道。但有些表单元素的样式没办法通过添加css样式来达到满意的效果,而且不同的浏览器之间设置的样式还存在兼容问题,比如下拉框。

本实例通过创建div和li等元素来生成一个模拟下拉框,以达到美化下拉框的效果。学习本教程之前,读者需要具备html和css技能,同时需要有简单的javascript基础。

先创建一个select元素,作为美化下拉框的数据来源,如下所示:

	<div class="select_wrap" id="selectWrap">
	  <dl>
	    <dt>请选择:</dt>
	    <dd>
	      <select id="selectElem">
	        <option value="1">北京</option>
	        <option value="2">上海</option>
	        <option value="3">广东</option>
	        <option value="4">湖南</option>
	        <option value="5">河北</option>
	        <option value="6">黑龙江</option>
	      </select>
	    </dd>
	  </dl>
	</div>

既然是做一个下拉框美化的效果,那肯定是需要用一些css样式来实现。读者可以根据自己有喜好编写,也可以直接复制以下代码:

	.select_wrap{
	  width:800px;
	  margin:30px auto;
	}
	.select_wrap dt{
	  float:left;
	  width:120px;
	  line-height:36px;
	  text-align:right;
	  font-size:14px;
	}
	.select_wrap dd{
	  margin-left:130px;
	  line-height:36px;
	}
	.select_wrap input[type=text],.select_wrap input[type=password]{
	  height:24px;
	  line-height:22px;
	  padding:0 5px;
	  border:1px solid #aaa;
	  border-radius:2px;
	}
	.select_wrap .btn{
	  padding:0 20px;
	  color:#fff;
	  cursor:pointer;
	  line-height:30px;
	  border:none;
	  margin-right:20px;
	  background:#108ee9;
	}
	.select_container{
	  position:relative;
	  display:inline-block;
	}
	.input_container:{
	  position:relative;
	}
	.input_container::after{
	  content:"";
	  position:absolute;
	  top:15px;
	  right:8px;
	  display:inline-block;
	  height:0px;
	  border:6px solid transparent;
	  border-top-color:#ccc;
	  pointer-events:none;
	}
	.input_container input{
	  height:30px;
	  line-height:28px;
	  padding:0 5px;
	  border:1px solid #aaa;
	  border-radius:4px;
	}
	.input_container input:focus{
	  border-color:#129cff;
	  outline:none;
	  box-shadow:0 0 6px #65bfff;
	}
	.select_container ul{
	  position:absolute;
	  top:35px;
	  width:100%;
	  margin:0;
	  padding:0;
	  background:#fff;
	  border-radius:4px;
	  box-shadow:0 0px 5px #ccc;
	}
	.select_container li{
	  list-style:none;
	  font-size:12px;
	  line-height:30px;
	  padding:0 10px;
	  cursor:pointer;
	}
	.select_container li:hover,.select_container li.cur{
	  background:#dbf0ff;
	}

前期工作做好之后,可以开始编写javascript代码了。按照惯例,还是把功能分析为一个一个步骤,再写具体的代码,思路会很清晰。

  1. 获取已有的下拉框元素

这里需要获取多个元素,首先通过id获取select元素,再找到select元素的父元素。因为生成的美化下拉框需要放到父元素中。还要获取到select所有的option子节点。如下所示:

	//获取下拉框
    var eSelect = document.getElementById('selectElem');
    //获取下拉框父节点
    var eDd = eSelect.parentNode;
    //获取下拉框选项
    var aOptions = eSelect.getElementsByTagName('option');
  1. 创建美化下拉框元素

先看一下美化后的下拉框,如下图所示:
表单美化
看下这个下拉框应该包含哪些元素,一个div元素把所有内容包含在里面;一个input文本框,显示选中的值;input元素还需要一个父级容器div元素;一个ul加一组li元素组成下拉列表。好,知道需要哪些元素了,先来创建文本框部分,如下所示:

	//创建美化select容器
    var eContainer = document.createElement('div');
    eContainer.className = 'select_container';
    //创建input父级容器
    var eInputCon = document.createElement('div');
    eInputCon.className = 'input_container';
    //创建input文本框,显示选中的值
    var eInput = document.createElement('input');
    //设置文本框不能输入
    eInput.readOnly = true;
    eInput.placeholder = '请选择';
    //把文本框放到容器中
    eInputCon.appendChild(eInput);

再来创建下拉列表。下拉列表可以创建一个ul元素,通过遍历aOptions下拉框选项,组合成li列表的字符串,通过innerHTML放到ul元素中,实现代码如下:

	//创建ul元素,作为下拉列表容器
    var eUl = document.createElement('ul');
    //声明变量,用于组合下拉列表的字符串
    var sLi = '';
    //遍历原有下拉框选项
    for(let i=0;i<aOptions.length;i++){
      //判断是否是当前选中的选项
      if(aOptions[i].selected){
        //下拉选项组合到下拉列表字符串,当前选中的选项需要加上class添加当前样式
        sLi += '<li class="cur" data-val="'+aOptions[i].value+'">'+aOptions[i].innerHTML+'</li>';
        //当前选中的选项显示到文本框中
        eInput.value = aOptions[i].innerHTML;
        //eUl元素设置data-val属性值为当前选中选项的值
        eUl.dataset.val = aOptions[i].value;
      }else{
        //非当前选中的选项,直接组合到下拉列表字符串,值设置到data-val属性中
        sLi += '<li data-val="'+aOptions[i].value+'">'+aOptions[i].innerHTML+'</li>';
      }
    }
    //下拉列表放到eUl元素中
    eUl.innerHTML = sLi;
    //默认隐藏下拉列表
    eUl.style.display = 'none';

把创建好的这些元素嵌套好,再添加到原下拉框的父元素中,并隐藏原有的下拉框,如下所示:

	//把文本框放到eContainer容器中
    eContainer.appendChild(eInputCon);
    //把下拉列表放到eContainer容器中
    eContainer.appendChild(eUl);
    //把eContainer元素放到select元素后面
    eDd.appendChild(eContainer);
    //隐藏原下拉框元素
    eSelect.style.display = 'none';

现在效果是有了,但下拉框的功能还没实现,还需要给这些美化后的元素添加事件。

  1. 实现打开下拉框功能

下拉框原有的功能是在文本框上点击鼠标,就会显示下拉列表。所以在eInput元素上绑定click事件来显示下拉列表,如下所示:

	//设置下拉框打开状态,0为关闭,1为打开
    var status = 0;
    //绑定click事件,用于显示下拉列表
    eInput.addEventListener('click',event=>{
      //判断下拉框是否已打开
      if(status){
        //下拉框打开则关闭下拉框
        eUl.style.display = 'none';
      }else{
        //下拉框关闭则打开下拉框
        eUl.style.display = 'block';
      }
      //修改下拉框状态
      status = +!status;
    },false);

可以看到,在eInput元素上点击,可以打开和关闭下拉框了。但选择下拉选项还是无效的。在下拉选项上也绑定click事件

  1. 下拉选项绑定click事件,点击时修改下拉框的值,如下所示:
	//获取下拉选项列表元素的集合
    var eLi = eUl.getElementsByTagName('li');
    //遍历下拉列表
    for(let i=0;i<eLi.length;i++){
      //给每一个li元素绑定点击事件
      eLi[i].addEventListener('click',(event)=>{
        //修改下拉框状态为已关闭状态
        status = 0;
        //清除所有列表的class
        for(let n=0;n<eLi.length;n++){
          eLi[n].className = '';
        }
        //激活当前列表选中样式
        eLi[i].className = 'cur';
        //设置下拉框当前选中值
        eUl.dataset.val = eLi[i].dataset.val;
        //还需要把值设置到原select元素上
        eSelect.value = eUl.dataset.val;
        //触发原select上的函数
        typeof eSelect.onchange=='function'&&select.onchange();
        //修改eInput元素显示的值
        eInput.value = eLi[i].innerHTML;
        //关闭下拉框
        eUl.style.display = 'none';
      },false);
    }

目前为止,功能基本完成。不过只能在选择选项后或再在文本框上点击才能关闭下拉框。所以还需要修改一下功能,在页面其他位置点击时也能关闭下拉框

  1. 在document绑定点击事件,用于关闭下拉框。

注意两点:一是在下拉框关闭时需要取消document上的绑定事件;二是eContainer元素上点击时需要阻止冒泡,否则下拉框会打不开了。修改后的代码如下:

	//设置下拉框打开状态,0为关闭,1为打开
    var status = 0;
    //绑定click事件,用于显示下拉列表
    eInput.addEventListener('click',event=>{
      //判断下拉框是否已打开
      if(status){
        //下拉框打开则关闭下拉框
        eUl.style.display = 'none';
        //取消document上的绑定事件
        document.removeEventListener('click',closeUl);
      }else{
        //下拉框关闭则打开下拉框
        eUl.style.display = 'block';
        //在document上绑定点击事件,用于关闭下拉框
        document.addEventListener('click',closeUl,false);
      }
      //修改下拉框状态
      status = +!status;
    },false);
    
    //获取下拉选项列表元素的集合
    var eLi = eUl.getElementsByTagName('li');
    //遍历下拉列表
    for(let i=0;i<eLi.length;i++){
      //给每一个li元素绑定点击事件
      eLi[i].addEventListener('click',(event)=>{
        //修改下拉框状态为已关闭状态
        status = 0;
        //清除所有列表的class
        for(let n=0;n<eLi.length;n++){
          eLi[n].className = '';
        }
        //激活当前列表选中样式
        eLi[i].className = 'cur';
        //设置下拉框当前选中值
        eUl.dataset.val = eLi[i].dataset.val;
        //还需要把值设置到原select元素上
        eSelect.value = eUl.dataset.val;
        //触发原select上的函数
        typeof eSelect.onchange=='function'&&select.onchange();
        //修改eInput元素显示的值
        eInput.value = eLi[i].innerHTML;
        //关闭下拉框
        eUl.style.display = 'none';
        //取消document上的绑定事件
        document.removeEventListener('click',closeUl);
      },false);
    }

    //绑定到document上关闭下拉框的函数
    function closeUl(){
      //修改下拉框状态为已关闭状态
      status = 0;
      //关闭下拉框
      eUl.style.display = 'none';
      //取消document上的绑定事件
      document.removeEventListener('click',closeUl);
    }

    //阻止冒泡,否则点击时冒泡到document上,会导致下拉框刚打开就关闭
    eContainer.addEventListener('click',event=>{
      event.stopPropagation();
    });

一个美化的下拉框已完成,读者动手一步一步实现理解应该会更深一些。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值