落日风儿 發表於 2021-1-18 21:24:00

纯原生javascript下拉框表单美化实例教程

<p>html的表单有很强大的功能,在web早期的时候,表单是页面向服务器发起通信的主要渠道。但有些表单元素的样式没办法通过添加css样式来达到满意的效果,而且不同的浏览器之间设置的样式还存在兼容问题,比如下拉框。</p>
<p>本实例通过创建div和li等元素来生成一个模拟下拉框,以达到美化下拉框的效果。学习本教程之前,读者需要具备html和css技能,同时需要有简单的javascript基础。</p>
<p>先创建一个select元素,作为美化下拉框的数据来源,如下所示:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">div </span><span style="color: rgba(255, 0, 0, 1)">class</span><span style="color: rgba(0, 0, 255, 1)">="select_wrap"</span><span style="color: rgba(255, 0, 0, 1)"> id</span><span style="color: rgba(0, 0, 255, 1)">="selectWrap"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">dl</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">dt</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>请选择:<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">dt</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">dd</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">select </span><span style="color: rgba(255, 0, 0, 1)">id</span><span style="color: rgba(0, 0, 255, 1)">="selectElem"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">option </span><span style="color: rgba(255, 0, 0, 1)">value</span><span style="color: rgba(0, 0, 255, 1)">="1"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>北京<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">option</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">option </span><span style="color: rgba(255, 0, 0, 1)">value</span><span style="color: rgba(0, 0, 255, 1)">="2"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>上海<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">option</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">option </span><span style="color: rgba(255, 0, 0, 1)">value</span><span style="color: rgba(0, 0, 255, 1)">="3"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>广东<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">option</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">option </span><span style="color: rgba(255, 0, 0, 1)">value</span><span style="color: rgba(0, 0, 255, 1)">="4"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>湖南<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">option</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">option </span><span style="color: rgba(255, 0, 0, 1)">value</span><span style="color: rgba(0, 0, 255, 1)">="5"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>河北<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">option</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">option </span><span style="color: rgba(255, 0, 0, 1)">value</span><span style="color: rgba(0, 0, 255, 1)">="6"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>黑龙江<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">option</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">select</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">dd</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">dl</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">div</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span></pre>
</div>
<p>&nbsp;</p>
<p>既然是做一个下拉框美化的效果,那肯定是需要用一些css样式来实现。读者可以根据自己有喜好编写,也可以直接复制以下代码:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(128, 0, 0, 1)">.select_wrap</span>{<span style="color: rgba(255, 0, 0, 1)">
width</span>:<span style="color: rgba(0, 0, 255, 1)">800px</span>;<span style="color: rgba(255, 0, 0, 1)">
margin</span>:<span style="color: rgba(0, 0, 255, 1)">30px auto</span>;
}<span style="color: rgba(128, 0, 0, 1)">
.select_wrap dt</span>{<span style="color: rgba(255, 0, 0, 1)">
float</span>:<span style="color: rgba(0, 0, 255, 1)">left</span>;<span style="color: rgba(255, 0, 0, 1)">
width</span>:<span style="color: rgba(0, 0, 255, 1)">120px</span>;<span style="color: rgba(255, 0, 0, 1)">
line-height</span>:<span style="color: rgba(0, 0, 255, 1)">36px</span>;<span style="color: rgba(255, 0, 0, 1)">
text-align</span>:<span style="color: rgba(0, 0, 255, 1)">right</span>;<span style="color: rgba(255, 0, 0, 1)">
font-size</span>:<span style="color: rgba(0, 0, 255, 1)">14px</span>;
}<span style="color: rgba(128, 0, 0, 1)">
.select_wrap dd</span>{<span style="color: rgba(255, 0, 0, 1)">
margin-left</span>:<span style="color: rgba(0, 0, 255, 1)">130px</span>;<span style="color: rgba(255, 0, 0, 1)">
line-height</span>:<span style="color: rgba(0, 0, 255, 1)">36px</span>;
}<span style="color: rgba(128, 0, 0, 1)">
.select_wrap input,.select_wrap input</span>{<span style="color: rgba(255, 0, 0, 1)">
height</span>:<span style="color: rgba(0, 0, 255, 1)">24px</span>;<span style="color: rgba(255, 0, 0, 1)">
line-height</span>:<span style="color: rgba(0, 0, 255, 1)">22px</span>;<span style="color: rgba(255, 0, 0, 1)">
padding</span>:<span style="color: rgba(0, 0, 255, 1)">0 5px</span>;<span style="color: rgba(255, 0, 0, 1)">
border</span>:<span style="color: rgba(0, 0, 255, 1)">1px solid #aaa</span>;<span style="color: rgba(255, 0, 0, 1)">
border-radius</span>:<span style="color: rgba(0, 0, 255, 1)">2px</span>;
}<span style="color: rgba(128, 0, 0, 1)">
.select_wrap .btn</span>{<span style="color: rgba(255, 0, 0, 1)">
padding</span>:<span style="color: rgba(0, 0, 255, 1)">0 20px</span>;<span style="color: rgba(255, 0, 0, 1)">
color</span>:<span style="color: rgba(0, 0, 255, 1)">#fff</span>;<span style="color: rgba(255, 0, 0, 1)">
cursor</span>:<span style="color: rgba(0, 0, 255, 1)">pointer</span>;<span style="color: rgba(255, 0, 0, 1)">
line-height</span>:<span style="color: rgba(0, 0, 255, 1)">30px</span>;<span style="color: rgba(255, 0, 0, 1)">
border</span>:<span style="color: rgba(0, 0, 255, 1)">none</span>;<span style="color: rgba(255, 0, 0, 1)">
margin-right</span>:<span style="color: rgba(0, 0, 255, 1)">20px</span>;<span style="color: rgba(255, 0, 0, 1)">
background</span>:<span style="color: rgba(0, 0, 255, 1)">#108ee9</span>;
}<span style="color: rgba(128, 0, 0, 1)">
.select_container</span>{<span style="color: rgba(255, 0, 0, 1)">
position</span>:<span style="color: rgba(0, 0, 255, 1)">relative</span>;<span style="color: rgba(255, 0, 0, 1)">
display</span>:<span style="color: rgba(0, 0, 255, 1)">inline-block</span>;
}<span style="color: rgba(128, 0, 0, 1)">
.input_container:</span>{<span style="color: rgba(255, 0, 0, 1)">
position</span>:<span style="color: rgba(0, 0, 255, 1)">relative</span>;
}<span style="color: rgba(128, 0, 0, 1)">
.input_container::after</span>{<span style="color: rgba(255, 0, 0, 1)">
content</span>:<span style="color: rgba(0, 0, 255, 1)">""</span>;<span style="color: rgba(255, 0, 0, 1)">
position</span>:<span style="color: rgba(0, 0, 255, 1)">absolute</span>;<span style="color: rgba(255, 0, 0, 1)">
top</span>:<span style="color: rgba(0, 0, 255, 1)">15px</span>;<span style="color: rgba(255, 0, 0, 1)">
right</span>:<span style="color: rgba(0, 0, 255, 1)">8px</span>;<span style="color: rgba(255, 0, 0, 1)">
display</span>:<span style="color: rgba(0, 0, 255, 1)">inline-block</span>; <span style="color: rgba(255, 0, 0, 1)">
height</span>:<span style="color: rgba(0, 0, 255, 1)">0px</span>;<span style="color: rgba(255, 0, 0, 1)">
border</span>:<span style="color: rgba(0, 0, 255, 1)">6px solid transparent</span>;<span style="color: rgba(255, 0, 0, 1)">
border-top-color</span>:<span style="color: rgba(0, 0, 255, 1)">#ccc</span>;<span style="color: rgba(255, 0, 0, 1)">
pointer-events</span>:<span style="color: rgba(0, 0, 255, 1)">none</span>;
}<span style="color: rgba(128, 0, 0, 1)">
.input_container input</span>{<span style="color: rgba(255, 0, 0, 1)">
height</span>:<span style="color: rgba(0, 0, 255, 1)">30px</span>;<span style="color: rgba(255, 0, 0, 1)">
line-height</span>:<span style="color: rgba(0, 0, 255, 1)">28px</span>;<span style="color: rgba(255, 0, 0, 1)">
padding</span>:<span style="color: rgba(0, 0, 255, 1)">0 5px</span>;<span style="color: rgba(255, 0, 0, 1)">
border</span>:<span style="color: rgba(0, 0, 255, 1)">1px solid #aaa</span>;<span style="color: rgba(255, 0, 0, 1)">
border-radius</span>:<span style="color: rgba(0, 0, 255, 1)">4px</span>;
}<span style="color: rgba(128, 0, 0, 1)">
.input_container input:focus</span>{<span style="color: rgba(255, 0, 0, 1)">
border-color</span>:<span style="color: rgba(0, 0, 255, 1)">#129cff</span>;<span style="color: rgba(255, 0, 0, 1)">
outline</span>:<span style="color: rgba(0, 0, 255, 1)">none</span>;<span style="color: rgba(255, 0, 0, 1)">
box-shadow</span>:<span style="color: rgba(0, 0, 255, 1)">0 0 6px #65bfff</span>;
}<span style="color: rgba(128, 0, 0, 1)">
.select_container ul</span>{<span style="color: rgba(255, 0, 0, 1)">
position</span>:<span style="color: rgba(0, 0, 255, 1)">absolute</span>;<span style="color: rgba(255, 0, 0, 1)">
top</span>:<span style="color: rgba(0, 0, 255, 1)">35px</span>;<span style="color: rgba(255, 0, 0, 1)">
width</span>:<span style="color: rgba(0, 0, 255, 1)">100%</span>;<span style="color: rgba(255, 0, 0, 1)">
margin</span>:<span style="color: rgba(0, 0, 255, 1)">0</span>;<span style="color: rgba(255, 0, 0, 1)">
padding</span>:<span style="color: rgba(0, 0, 255, 1)">0</span>;<span style="color: rgba(255, 0, 0, 1)">
background</span>:<span style="color: rgba(0, 0, 255, 1)">#fff</span>;<span style="color: rgba(255, 0, 0, 1)">
border-radius</span>:<span style="color: rgba(0, 0, 255, 1)">4px</span>;<span style="color: rgba(255, 0, 0, 1)">
box-shadow</span>:<span style="color: rgba(0, 0, 255, 1)">0 0px 5px #ccc</span>;
}<span style="color: rgba(128, 0, 0, 1)">
.select_container li</span>{<span style="color: rgba(255, 0, 0, 1)">
list-style</span>:<span style="color: rgba(0, 0, 255, 1)">none</span>;<span style="color: rgba(255, 0, 0, 1)">
font-size</span>:<span style="color: rgba(0, 0, 255, 1)">12px</span>;<span style="color: rgba(255, 0, 0, 1)">
line-height</span>:<span style="color: rgba(0, 0, 255, 1)">30px</span>;<span style="color: rgba(255, 0, 0, 1)">
padding</span>:<span style="color: rgba(0, 0, 255, 1)">0 10px</span>;<span style="color: rgba(255, 0, 0, 1)">
cursor</span>:<span style="color: rgba(0, 0, 255, 1)">pointer</span>;
}<span style="color: rgba(128, 0, 0, 1)">
.select_container li:hover,.select_container li.cur</span>{<span style="color: rgba(255, 0, 0, 1)">
background</span>:<span style="color: rgba(0, 0, 255, 1)">#dbf0ff</span>;
}</pre>
</div>
<p>&nbsp;</p>
<p>前期工作做好之后,可以开始编写javascript代码了。按照惯例,还是把功能分析为一个一个步骤,再写具体的代码,思路会很清晰。</p>
<p>1. 获取已有的下拉框元素</p>
<p>这里需要获取多个元素,首先通过id获取select元素,再找到select元素的父元素。因为生成的美化下拉框需要放到父元素中。还要获取到select所有的option子节点。如下所示:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获取下拉框</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> eSelect = document.getElementById('selectElem'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获取下拉框父节点</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> eDd =<span style="color: rgba(0, 0, 0, 1)"> eSelect.parentNode;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获取下拉框选项</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> aOptions = eSelect.getElementsByTagName('option');</pre>
</div>
<p>&nbsp;</p>
<p>2. 创建美化下拉框元素</p>
<p>先看一下美化后的下拉框,如下图所示:</p>
<p><img src="https://img2020.cnblogs.com/blog/1260765/202101/1260765-20210118205752587-625640960.png"></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;想一下这个下拉框应该包含哪些元素,一个div元素把所有内容包含在里面;一个input文本框,显示选中的值;input元素还需要一个父级容器div元素;一个ul加一组li元素组成下拉列表。好,知道需要哪些元素了,先来创建文本框部分,如下所示:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">创建美化select容器</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> eContainer = document.createElement('div'<span style="color: rgba(0, 0, 0, 1)">);
eContainer.className </span>= 'select_container'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">创建input父级容器</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> eInputCon = document.createElement('div'<span style="color: rgba(0, 0, 0, 1)">);
eInputCon.className </span>= 'input_container'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">创建input文本框,显示选中的值</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> eInput = document.createElement('input'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">设置文本框不能输入</span>
eInput.readOnly = <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
eInput.placeholder </span>= '请选择'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">把文本框放到容器中</span>
eInputCon.appendChild(eInput);</pre>
</div>
<p>再来创建下拉列表。下拉列表可以创建一个ul元素,通过遍历aOptions下拉框选项,组合成li列表的字符串,通过innerHTML放到ul元素中,实现代码如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">创建ul元素,作为下拉列表容器</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> eUl = document.createElement('ul'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">声明变量,用于组合下拉列表的字符串</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> sLi = ''<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">遍历原有下拉框选项</span>
<span style="color: rgba(0, 0, 255, 1)">for</span>(let i=0;i&lt;aOptions.length;i++<span style="color: rgba(0, 0, 0, 1)">){
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">判断是否是当前选中的选项</span>
<span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)">(aOptions.selected){
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">下拉选项组合到下拉列表字符串,当前选中的选项需要加上class添加当前样式</span>
    sLi += '&lt;li class="cur" data-val="'+aOptions.value+'"&gt;'+aOptions.innerHTML+'&lt;/li&gt;'<span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">当前选中的选项显示到文本框中</span>
    eInput.value =<span style="color: rgba(0, 0, 0, 1)"> aOptions.innerHTML;
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">eUl元素设置data-val属性值为当前选中选项的值</span>
    eUl.dataset.val =<span style="color: rgba(0, 0, 0, 1)"> aOptions.value;
}</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">{
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">非当前选中的选项,直接组合到下拉列表字符串,值设置到data-val属性中</span>
    sLi += '&lt;li data-val="'+aOptions.value+'"&gt;'+aOptions.innerHTML+'&lt;/li&gt;'<span style="color: rgba(0, 0, 0, 1)">;
}
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">下拉列表放到eUl元素中</span>
eUl.innerHTML =<span style="color: rgba(0, 0, 0, 1)"> sLi;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">默认隐藏下拉列表</span>
eUl.style.display = 'none';</pre>
</div>
<p>把创建好的这些元素嵌套好,再添加到原下拉框的父元素中,并隐藏原有的下拉框,如下所示:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">把文本框放到eContainer容器中</span>
<span style="color: rgba(0, 0, 0, 1)">eContainer.appendChild(eInputCon);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">把下拉列表放到eContainer容器中</span>
<span style="color: rgba(0, 0, 0, 1)">eContainer.appendChild(eUl);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">把eContainer元素放到select元素后面</span>
<span style="color: rgba(0, 0, 0, 1)">eDd.appendChild(eContainer);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">隐藏原下拉框元素</span>
eSelect.style.display = 'none';</pre>
</div>
<p>现在效果是有了,但下拉框的功能还没实现,还需要给这些美化后的元素添加事件。</p>
<p>&nbsp;</p>
<p>3. 实现打开下拉框功能</p>
<p>下拉框原有的功能是在文本框上点击鼠标,就会显示下拉列表。所以在eInput元素上绑定click事件来显示下拉列表,如下所示:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">设置下拉框打开状态,0为关闭,1为打开</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> status = 0<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">绑定click事件,用于显示下拉列表</span>
eInput.addEventListener('click',event=&gt;<span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">判断下拉框是否已打开</span>
<span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)">(status){
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">下拉框打开则关闭下拉框</span>
    eUl.style.display = 'none'<span style="color: rgba(0, 0, 0, 1)">;
}</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">{
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">下拉框关闭则打开下拉框</span>
    eUl.style.display = 'block'<span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">修改下拉框状态</span>
status = +!<span style="color: rgba(0, 0, 0, 1)">status;
},</span><span style="color: rgba(0, 0, 255, 1)">false</span>);</pre>
</div>
<p>可以看到,在eInput元素上点击,可以打开和关闭下拉框了。但选择下拉选项还是无效的。在下拉选项上也绑定click事件</p>
<p>&nbsp;</p>
<p>4. 下拉选项绑定click事件,点击时修改下拉框的值,如下所示:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获取下拉选项列表元素的集合</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> eLi = eUl.getElementsByTagName('li'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">遍历下拉列表</span>
<span style="color: rgba(0, 0, 255, 1)">for</span>(let i=0;i&lt;eLi.length;i++<span style="color: rgba(0, 0, 0, 1)">){
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">给每一个li元素绑定点击事件</span>
eLi.addEventListener('click',(event)=&gt;<span style="color: rgba(0, 0, 0, 1)">{
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">修改下拉框状态为已关闭状态</span>
    status = 0<span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">清除所有列表的class</span>
    <span style="color: rgba(0, 0, 255, 1)">for</span>(let n=0;n&lt;eLi.length;n++<span style="color: rgba(0, 0, 0, 1)">){
      eLi.className </span>= ''<span style="color: rgba(0, 0, 0, 1)">;
    }
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">激活当前列表选中样式</span>
    eLi.className = 'cur'<span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">设置下拉框当前选中值</span>
    eUl.dataset.val =<span style="color: rgba(0, 0, 0, 1)"> eLi.dataset.val;
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">还需要把值设置到原select元素上</span>
    eSelect.value =<span style="color: rgba(0, 0, 0, 1)"> eUl.dataset.val;
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">触发原select上的函数</span>
    <span style="color: rgba(0, 0, 255, 1)">typeof</span> eSelect.onchange=='function'&amp;&amp;<span style="color: rgba(0, 0, 0, 1)">select.onchange();
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">修改eInput元素显示的值</span>
    eInput.value =<span style="color: rgba(0, 0, 0, 1)"> eLi.innerHTML;
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">关闭下拉框</span>
    eUl.style.display = 'none'<span style="color: rgba(0, 0, 0, 1)">;
},</span><span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">);
}</span></pre>
</div>
<p>目前为止,功能基本完成。不过只能在选择选项后或再在文本框上点击才能关闭下拉框。所以还需要修改一下功能,在页面其他位置点击时也能关闭下拉框</p>
<p>&nbsp;</p>
<p>5. 在document绑定点击事件,用于关闭下拉框。</p>
<p>注意两点:一是在下拉框关闭时需要取消document上的绑定事件;二是eContainer元素上点击时需要阻止冒泡,否则下拉框会打不开了。修改后的代码如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">设置下拉框打开状态,0为关闭,1为打开</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> status = 0<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">绑定click事件,用于显示下拉列表</span>
eInput.addEventListener('click',event=&gt;<span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">判断下拉框是否已打开</span>
<span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)">(status){
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">下拉框打开则关闭下拉框</span>
    eUl.style.display = 'none'<span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">取消document上的绑定事件</span>
    document.removeEventListener('click'<span style="color: rgba(0, 0, 0, 1)">,closeUl);
}</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">{
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">下拉框关闭则打开下拉框</span>
    eUl.style.display = 'block'<span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">在document上绑定点击事件,用于关闭下拉框</span>
    document.addEventListener('click',closeUl,<span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">);
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">修改下拉框状态</span>
status = +!<span style="color: rgba(0, 0, 0, 1)">status;
},</span><span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">);

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

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

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">阻止冒泡,否则点击时冒泡到document上,会导致下拉框刚打开就关闭</span>
eContainer.addEventListener('click',event=&gt;<span style="color: rgba(0, 0, 0, 1)">{
event.stopPropagation();
});</span></pre>
</div>
<p>一个美化后的下拉框已经完成,如果动手一步一步实现它,理解应该会更深一些。</p><br><br>
来源:https://www.cnblogs.com/jiangweiping/p/14295286.html
頁: [1]
查看完整版本: 纯原生javascript下拉框表单美化实例教程