效果图
注:值是根据原生select中的值来动态获取并进行分类
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>index</title> <link rel="stylesheet" href="style.css"> </head> <body> <div class="container"> <div id="wrap"> <div class="div1"> <div class="title">自定义select</div> <div class="select"> <select id="select-name"> <option value="" disabled="true">请选择</option> </select> <div class="s select-box"> <div class="s select-head"> <span class="s">未选择</span> <i class="s"></i> </div> <div class="s select-body"> <div class="s search-input"> <input class="s" type="text" placeholder="搜索"> <i class="s"></i> </div> <div class="s value-body"> </div> </div> </div> </div> </div> <div class="outdiv"> <p id="out"></p> </div> <div class="div2"> <div class="title">原生select</div> <select> <option value="1" type="构建工具">Babel</option> <option value="2" type="构建工具">Webpack</option> <option value="3" type="构建工具">Rollup</option> <option value="4" type="前端框架">Vue</option> <option value="5" type="前端框架">Angular</option> <option value="6" type="前端框架">React</option> <option value="7" type="前端框架">Nerv</option> </select> </div> </div> </div> <script src="index.js"></script> </body> </html>
style.css
.container{ width:100%; height:100vh; text-align: center; } #wrap{ height:170px; position: relative; top:50%; margin-top:-85px; text-align: center; } .div1{ text-align: center; } .div2{ text-align: center; } .title{ color: rgb(75,151,251); margin-bottom: 10px; } div.select{ width: 200px; position: relative; left: 50%; margin-left: -100px; } div.select select{ display: none; } div.select-box{ width: 200px; margin: 20px 20px; } div.select-head{ position: relative; height: 30px; width: 100%; display: flex; border: solid 1px rgb(75,151,251); align-items: center; cursor: pointer; } div.select-head span{ font-size: 16px; margin-left: 5px; color: #AAA; } div.select-head span.fill{ color: #000; } div.select-head i{ position: absolute; height: 30px; width: 30px; right: -1px; background: url(./arrow.png) center center no-repeat; background-size: 30px auto; } div.select-body{ display: none; width: 100%; border: solid 1px rgb(75,151,251); border-top: none; } div.search-input{ position: relative; height: 40px; } div.search-input input{ height: 30px; width: 150px; margin: 5px 8px; text-indent: 10px; padding-right: 30px; } div.search-input i{ position: absolute; display: block; height: 20px; width: 20px; top: 12px; right: 15px; background-image: url(./search-normal.png); background-size: 20px 20px; cursor: pointer; } div.search-input i:hover{ background-image: url(./search-active.png); } div.value-body{ max-height: 150px; overflow-y: auto; text-align: left; overflow-x: hidden; } div.value-body li{ display: flex; height: 24px; padding: 5px 5px 5px 30px; font-size: 14px; align-items: center; cursor: pointer; position: relative; } div.value-body span{ display: block; font-weight: bold; font-size: 16px; margin:10px; } div.value-body span+li{ margin-top: 14px; } div.value-body li:hover,li.active{ background-color: #F5F6FA; } div.value-body li.active{ background-color: rgb(75,151,251); color:white; } div.value-body li.none,div.none{ display: none; } div.value-body div{ text-align: center; height: 30px; line-height: 30px; color: #AAA; }
index.js
window.onload = function () { //初始化生成DOM元素 function init(){ var types=[]; // 根据原生的select中的每一项提供的类型和值,使用脚本获取,然后进行分类重新显示 var options=document.querySelectorAll(\'.div2 option\'); var templates=\'\';//插入到select的总模板 var se_templates=\'\';//插入到div的总模板 var tem=\'\';//select 某个分类的总模板 var se_tem=\'\';//div 某个分类的总模板 options.forEach( function(element, index) { var type=element.getAttribute(\'type\'); //创建分类 if (types.indexOf(type)==-1){ types.push(type) tem=`<span>`+type+`</span>`; se_tem=`<span>`+type+`</span>`; var lis=\'\';//select 某个分类下的项目模板 var se_lis=\'\';//div 某个分类下的项目模板 //根据分类创建选项 options.forEach( function(ele) { var value=ele.getAttribute(\'value\'); var text=ele.innerText; if(ele.getAttribute(\'type\')==type){ lis+=`<li data-value="`+text+`">`+text+`</li>`; se_lis+=`<option value="`+text+`">`+text+`</option>`; } }); tem+=lis; se_tem+=se_lis; templates+=tem; se_templates+=se_tem; } }); document.querySelector(\'.value-body\').innerHTML=templates; document.querySelector(\'#select-name\').innerHTML=se_templates; } init(); var out=document.querySelector(\'#out\'); var last_out=\'未选择--undefined\'; //清空select的value document.querySelector(\'div.select>select\').value = \'\' /** * 点击自定义的select框开启或收回选择框 */ document.querySelector(\'div.select-head\').onclick = function () { //清空输入框内容 document.querySelector(\'div.search-input>input\').value = \'\' document.querySelectorAll(\'div.value-body>li\').forEach( function(element, index) { if (element.classList.contains(\'active\')) { element.classList = \'active\' }else { element.classList = \'\' } }); // document.querySelector(\'div.value-body>div\').classList = \'none\' var select_body = document.querySelector(\'div.select-body\') if (select_body.style.display == \'block\') select_body.style.display = \'none\' else select_body.style.display = \'block\' }; /** * 点击空白处关闭select框 */ document.onclick = function (argument) { if(!argument.target.classList.contains(\'s\')){ var select_body = document.querySelector(\'div.select-body\') if (select_body.style.display == \'block\') select_body.style.display = \'none\' } } /** * 自定义的select的选值功能 */ document.querySelectorAll(\'div.value-body>li\').forEach( function(element, index) { element.onclick = function () { //初始化下样式 document.querySelectorAll(\'div.value-body>li\').forEach( function(element, index) { element.classList = \'\' }); element.classList = \'active\' //更新select框的value和自定义的select框的value var data_value = element.getAttribute(\'data-value\') var select_head_span = document.querySelector(\'div.select-head>span\') document.querySelector(\'div.select>select\').value = data_value select_head_span.innerHTML = data_value out.innerHTML= \'之前的值是:\'+last_out+\'<br>改变后的值是:\'+data_value last_out=data_value; if(!select_head_span.classList.contains(\'fill\')) select_head_span.classList = \'fill\' //关闭select-body document.querySelector(\'div.select-body\').style.display = \'none\' } }); /** * 搜素功能实现 */ document.querySelector(\'div.search-input>input\').oninput = function () { var input_value = document.querySelector(\'div.search-input>input\').value if(input_value == \'\') { document.querySelectorAll(\'div.value-body>li\').forEach( function(element, index) { if (element.classList.contains(\'active\')) { element.classList = \'active\' }else { element.classList = \'\' } }); }else{ document.querySelectorAll(\'div.value-body>li\').forEach( function(element, index) { if(element.getAttribute(\'data-value\').toLowerCase().indexOf(input_value.toLowerCase()) == -1){ if (element.classList.contains(\'active\')) { element.classList += \' none\' }else { element.classList = \'none\' } }else { if(element.classList.contains(\'none\')) { document.querySelectorAll(\'div.value-body>li\').forEach( function(element, index) { if (element.classList.contains(\'active\')) { element.classList = \'active\' }else { element.classList = \'\' } }); } } }); } //记一下结果数量 var length = 0 document.querySelectorAll(\'div.value-body>li\').forEach( function(element, index) { if (!element.classList.contains(\'none\')) length++ }); if (length == 0) { document.querySelector(\'div.value-body>li\').classList = \'\' }else{ document.querySelector(\'div.value-body>li\').classList = \'none\' } } };