zoukankan      html  css  js  c++  java
  • js自定义的可分类可搜索的下拉框组件

    html5搜索框结合datalist可以实现带搜索功能的下拉框

    不过尝试了下,使用optgroup分组发现没效果

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>search</title>
    </head>
    <body>
        <input type="text" list="data" id="mylist">
        <datalist id="data">
            <optgroup label="基础"> 
                <option value="html">html</option>
                <option value="css">css</option>
                <option value="js">js</option>
            </optgroup>
            <optgroup label="框架"> 
                <option value="vue">vue</option>
                <option value="react">react</option>
            </optgroup>
        </datalist>
    </body>
    </html>

    自己写一个可以搜索和已经归类的下拉框

    放出效果图

    目录结构

    index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>search</title>
        <style>
            *{
                margin:0;
                padding:0;
                box-sizing: border-box;
            }
            body{
                background:#eee;
                font-size:14px;
                font-family: "微软雅黑"
            }
            @font-face {
              font-family: "iconfont";
              src: url('font/iconfont.eot?t=1585396588464'); /* IE9 */
              src: url('font/iconfont.eot?t=1585396588464#iefix') format('embedded-opentype'), /* IE6-IE8 */
              url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAKYAAsAAAAABkAAAAJMAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCCcApMZwE2AiQDCAsGAAQgBYRtBy8bjAXILjGFawcSqIK0GIFz91T6AwAgHv7b73/7zJ1vKlE0i0dIpN8wrSS8ZUpnkdXy2/81TZGEy6suyyoakEJ/kH/AuYwkCjn2s2zkJuQmXOvbvU6Jm2QlEFVylb5XprzPczm9CXQg8wOd42gu2osWTepFYS8OKMC9MIoTKaGMG8YueIH3CVTr15PZ29g7hLLMXhaIS8fSoFxIyDIrVwrlDXuzeK5MZXqafvAs+n58tRxlkrKC3XB4bd2E2QdOrnhSeiIgJAnocBkKzAKZOG0s7MsJxuVUF/KGwbFqgw9KpcAvjuoR7K+zq2tBL1SfSfP0Ry0neKxB7cO0Se8i2u/fc/X1J21nl8Xdm7a2Ox0XLy0t51aL0uL7sT9/ovl6t/vdf42boZ8VQ6kjg6Dl4adXWmv/K2syeJfLyJ3hEKjcTzD4H9rAnmwYbF/KmtY4nLSfp6laNUpwpNn/VGfbySuhUtuEUIW+DIVKo2RmZ1GmxirKVdpEtRmbh2u0YDmRqzDtFiA0ekNS7y0KjX7JzP6hTLsVyjVGDtXOo+XMGuPhVHeZNCET9Qt0jChUbkCqce0+WSe+xnlDxB8Tp04ax4NRubxJIfESG9JTayKiUHEU4AZ4jHw/wpgjlwwZ2CLxdDhUTS8aGFEAVbsY0QhiQroLyGGIhFQwWlQrn99HLCd8Gu7oqiuPEZZyJkdjA6MB5KY1HNT1KM+kTlkmhFCQwiIBtAFmEZ8vguLmWS5iEAP2hFxsauj0U0Otg+3twd8dg2q2K4UzpVB2x9F8DQAAAA==') format('woff2'),
              url('font/iconfont.woff?t=1585396588464') format('woff'),
              url('font/iconfont.ttf?t=1585396588464') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
              url('font/iconfont.svg?t=1585396588464#iconfont') format('svg'); /* iOS 4.1- */
            }
    
            .iconfont {
              font-family: "iconfont" !important;
              font-size: 16px;
              font-style: normal;
              -webkit-font-smoothing: antialiased;
              -moz-osx-font-smoothing: grayscale;
            }
            .icon-xiala:before {
              content: "e65c";
              color:#fff;
            }
            .container{
                margin:50px auto;
                width:200px;
                
            }
            .input-box{
                position: relative;
                width:202px;
                height:25px;
            }
            .input{
                width:200px;
                border:1px solid rgb(75,151,252);    
                height:25px;    
                padding:3px 8px;    
            }
            .btn{
                position: absolute;
                right:0;
                top:0;
                width:25px;
                height:25px;
                height:100%;
                background-color: rgb(75,151,252);    
                text-align:center;
                cursor: pointer;
            }
            .list-box{
                width:200px;
                height:auto;
                overflow-y:scroll;
                background-color: #fff;
                padding:5px;
                max-height:200px;
                display: none;
            }
            .search{
                width:100%;
                margin-bottom:5px;
                padding:2px;
    
            }
            input::-webkit-input-placeholder{
                font-size:12px;
            }
            dl{
                width:100%;
                height:auto;
                line-height:25px;
                margin-top:5px;
            }
            dd{
                padding-left:10px;
                cursor: pointer;
            }
            dt{
                font-weight:bold;
            }
            .info{
                text-align:center;
            }
        </style>
    </head>
    <body>
        <div class="container">
            <div class="input-box">
                <input type="text" class="input">
                <div class="btn"><i class="iconfont icon-xiala"></i></div>
            </div>
            <div class="list-box">
                <input type="text" class="search" placeholder="搜索">
                <!-- <dl>
                    <dt>基础</dt>
                    <dd>html</dd>
                    <dd>css</dd>
                    <dd>js</dd>
                    <dd>jQuery</dd>
                </dl>
                <dl>
                    <dt>框架</dt>
                    <dd>vue</dd>
                    <dd>react</dd>
                    <dd>angular</dd>
                </dl> -->
            </div>
        </div>
        <div class="info">
            <p>之前的值是:<span class="prev"></span></p>
            <p>改变后的值是:<span class="now"></span></p>
        </div>
    
        <script src="data.js"></script>
        <script src="index.js"></script>
        <script>
            window.onload=function(){
                let mysearch=new $Search({
                    data
                });
            }
        </script>
    </body>
    </html>

    data.js  数据

    //数据对象
    const data={
        "基础":["html","css","js","jQuery"],
        "框架":["vue","react","angular"]
    }

    index.js

    (function(window,document){
    
        //构造函数
        function Search(data){
            this.data=data.data;
            this.prevInfo="空";
            this.nowInfo="空";
            this.showListFlag=false;
            
            this.toDom(this.data);//生成DOM
            this.bindSearch();//绑定搜索框事件
            this.clickDD();//点击DD事件
        }
    
        //生成DOM
        Search.prototype.toDom=function(data){
            let templates=``;
    
            for(let d in data){    
    
                let ddTemplates="";
                for(let i=0;i<data[d].length;i++){
                    ddTemplates+=`
                        <dd>${ data[d][i] }</dd>
                    `;
                }
    
                templates+=`
                    <dl>
                        <dt>${ d }</dt>
                        `+
                        ddTemplates
                        +`
                    </dl>
                `;
            }
    
            document.querySelector(".list-box").innerHTML+=templates;
            document.querySelector(".prev").innerHTML=this.prevInfo;
            document.querySelector(".now").innerHTML=this.nowInfo;
    
            //点击显示下拉框
            document.querySelector(".input-box").addEventListener("click",()=>{
                if(this.showListFlag){
                    this.hideList();
                }else{
                    this.showList();
                }
                
            })
        }
    
        //隐藏下拉框
        Search.prototype.hideList=function(){
            document.querySelector(".list-box").style.display="none";
            document.querySelector(".search").value="";
            this.showListFlag=true;
        }
    
        //显示下拉框
        Search.prototype.showList=function(){
            document.querySelector(".list-box").style.display="block";
            document.querySelector(".search").value="";
            let dds=document.querySelectorAll("dd");
            
            dds.forEach(function(dd,index){
                dd.style.display="block";
            })
            this.showListFlag=true;
        }
    
        //绑定搜索框事件
        Search.prototype.bindSearch=function(){
            let search=document.querySelector(".search");
    
            search.addEventListener("keyup",()=>{
                let str=search.value;    
                this.hideDD(str);//隐藏不包含搜索内容的dd
            })
        }
    
        //隐藏不包含搜索内容的dd
        Search.prototype.hideDD=function(str){
            let dds=document.querySelectorAll("dd");
            
            dds.forEach(function(dd,index){
                dd.style.display="block";
    
                //不包含搜索内容的dd
                if(dd.innerText.indexOf(str)===-1){
                    //隐藏
                    dd.style.display="none";
                }
                
            })
        }
    
        //点击dd事件
        Search.prototype.clickDD=function(){
            //事件代理
            document.querySelector(".list-box").addEventListener("click",(e)=>{
                if(e.target.nodeName!=="DD") return;
    
                if(this.showListFlag){
                    this.hideList();
                }else{
                    this.showList();
                }
                this.showListFlag=!this.showListFlag;
                
                //更新info
                document.querySelector(".prev").innerHTML=document.querySelector(".input").value;            
    
                let val=e.target.innerText;
                document.querySelector(".input").value=e.target.innerText;
    
                //更新info
                document.querySelector(".now").innerHTML=document.querySelector(".input").value;
            })
            
        }
    
        window.$Search=Search;
    })(window,document);
  • 相关阅读:
    【Python】【解决】UnicodeDecodeError: 'ascii' codec can't decode byte 0xe5 in position 1: ordinal not in range(128)
    【小技巧】强制重启无线网卡,解决“区域中找不到无线网络,请确定您计算机上的无线开关已启用”问题
    【小技巧】9针USB转串口简易连通性测试,附25针转9针
    【ACM】HDU1008 Elevator 新手题前后不同的代码版本
    【Android】命令行jarsigner签字和解决找不到证书链错误
    LeetCode 【47. Permutations II】
    LeetCode 【46. Permutations】
    Python asyncio库的学习和使用
    LeetCode 【190. Reverse Bits】
    LeetCode 【21. Merge Two Sorted Lists】
  • 原文地址:https://www.cnblogs.com/chenyingying0/p/12589871.html
Copyright © 2011-2022 走看看