首页 > 其他分享 >原生JS实现城市选择(输入提示)组控件

原生JS实现城市选择(输入提示)组控件

时间:2024-09-02 16:54:21浏览次数:6  
标签:原生 控件 style const city cityPopup JS getElementById document

先看效果图:

功能需求:

  • 国内城市、国际城市切换
  • 首字母索引分类
  • 输入变化提示

HTML代码

<div class="m-list">
       <div class="g-sch">
        <ul class="f-cb z-blankhide">
         <li class="first">
          <p class="u-unit">
           <label class="u-lab"><b>出发</b></label>
           <span class="u-fromE"><span class="u-ipt s-w168"><input data-type="depart" oninput="inputChange(event)"
              onfocus="openCityPopup(event)" type="text" class="s-w168" id="departCity" /></span></span>
          </p>
          <span class="u-change"><i class="s-png"></i></span>
         </li>
         <li>
          <p class="u-unit">
           <label class="u-lab"><b>到达</b></label>
           <span class="u-fromE"><span class="u-ipt"><input data-type="arrive" oninput="inputChange(event)"
              onfocus="openCityPopup(event)" type="text" class="s-w168" id="arriveCity" /></span></span>
          </p>
         </li>
         <li>
          <p class="u-unit">
           <label class="u-lab"><b>出发日期</b></label>
           <span class="u-fromE"><span class="u-ipt"><input type="date" class="s-w168" /></span>
          </p>
         </li>
         <li>
          <p class="u-unit">
           <label class="u-lab"><i class="u-checkbox s-png"></i><b class="s-fc-999">返回日期</b></label>
           <span class="u-fromE"><span class="u-ipt"><input type="date" class="s-w168" /></span>
          </p>
         </li>
         <li class="last">
          <a href="details.html" class="u-a1">搜索</a>
          <a href="javascript:;" class="u-a2"><span>搜索更多条件</span><i class="s-png"></i></a>
         </li>
        </ul>
        <ul class="f-cb z-divShow" style="display:none">
         <li>
          <p class="u-unit f-fl">
           <label class="u-lab"><b>乘客类型</b></label>
           <span class="u-fromE">
            <span class="u-select s-w178 z-blankhide">
             <span class="u-select-tt"><span>成人</span><i class="s-png"></i></span>
             <span class="u-select-ct" style="display:none"><a href="">成人</a><br /><a href="">儿童(2-12岁)</a></span>
            </span>
           </span>
          </p>
         </li>
         <li>
          <p class="u-unit f-fl">
           <label class="u-lab"><b>乘客数量</b></label>
           <span class="u-fromE">
            <span class="u-select s-w178 z-blankhide">
             <span class="u-select-tt"><span>1</span><i class="s-png"></i></span>
             <span class="u-select-ct" style="display:none"><a href="">1</a><a href="">2</a><br /><a
               href="">3</a><br /><a href="">4</a></span>
            </span>
           </span>
          </p>
         </li>
         <li>
          <p class="u-unit f-fl">
           <label class="u-lab"><b>舱位等级</b></label>
           <span class="u-fromE">
            <span class="u-select s-w178 z-blankhide">
             <span class="u-select-tt"><span>经济舱</span><i class="s-png"></i></span>
             <span class="u-select-ct" style="display:none"><a href="">豪华经济舱</a><a href="">头等舱</a><br /><a
               href="">商务舱</a><br /><a href="">混合舱</a></span>
            </span>
           </span>
          </p>
         </li>
         <li>
          <p class="u-unit">
           <label class="u-lab"><b>航空公司</b></label>
           <span class="u-fromE"><span class="u-ipt z-blankhide"><input type=""
              class="s-w168" /><b>中文或代码</b></span></span>
          </p>
         </li>
        </ul>
        <p class="u-tishi">如果是多人出游,建议您搜索时选择实际的乘客数量,以便获得更优惠的价格。</p>
       </div>
      </div>

 <dialog id="cityPopup" class="cityPopup">
  <div class="switchBox">
   <ul class="switch">
    <li class="menu" onclick="clickSwitch(event,0)">国内</li>
    <li class="menu" onclick="clickSwitch(event,1)">国际</li>
   </ul>
  </div>
  <div class="citySelectBox">
   <p class="title">支持中文/拼音/简拼/三字码输入</p>
   <ul id="indexList" class="indexList">
    <li id="index1" class="index" data-citySpell="热门" onclick="clickTab(event,0)">热门</li>
    <li id="index2" class="index" data-citySpell="ABCD" onclick=" clickTab(event,1)">ABCD</li>
    <li id="index3" class="index" data-citySpell="EFGH" onclick="clickTab(event,2)">EFGH</li>
    <li id="index4" class="index" data-citySpell="JKLM" onclick="clickTab(event,3)">JKLM</li>
    <li id="index5" class="index" data-citySpell="NPQRS" onclick="clickTab(event,4)">NPQRS
    </li>
    <li id="index6" class="index" data-citySpell="TWX" onclick="clickTab(event,5)">TWX
    </li>
    <li id="index7" class="index" data-citySpell="YZ" onclick="clickTab(event,6)">YZ</li>
   </ul>
   <ul id="interList" class="indexList">
    <li id="index1" class="index" data-citySpell="热门" onclick="clickTab(event,7)">热门</li>
    <li id="index2" class="index" data-citySpell="亚洲" onclick=" clickTab(event,8)">亚洲</li>
    <li id="index2" class="index" data-citySpell="欧洲" onclick=" clickTab(event,9)">欧洲</li>
    <li id="index2" class="index" data-citySpell="美洲" onclick=" clickTab(event,10)">美洲</li>
    <li id="index2" class="index" data-citySpell="非洲" onclick=" clickTab(event,11)">非洲</li>
    <li id="index2" class="index" data-citySpell="大洋洲" onclick=" clickTab(event,12)">大洋洲</li>
   </ul>
   <div class="city-box" id="city-box">
   </div>
  </div>
 </dialog>
 <div id="regListPopup" class="regListPopup">

 </div>

功能实现

  • 输入框输入时,触发自动搜索并展示,因为是本地搜索,所以需要本地数据,代码中所用数据格式为[''beijing|北京|bj|PEK'',"......"]
    // 手动输入变化时自动匹配
    function inputChange() {
        const cityPopup = document.getElementById("cityPopup");
        const regListPopup = document.querySelector(".regListPopup")
        const regListStyle = document.getElementsByClassName("regListPopup")[0]
        const regDiv = document.createElement('div')
        let inputVal
        this.regCityList = []
        if (this.inputType == "depart") {
            inputVal = document.getElementById("departCity").value
            regListStyle.style.top = "650px"
            regListStyle.style.left = "420px"
        } else {
            inputVal = document.getElementById("arriveCity").value
            regListStyle.style.top = "650px"
            regListStyle.style.left = "650px"
        }
        regListStyle.style.display = "block"
        cityPopup.close()
        console.log(inputVal);
        if (!inputVal) { //输入框内容为空
            regListStyle.style.display = "none"
        } else {
            for (let i = 0; i < searchArray.length; i++) {  //匹配输入框内容
                if (searchArray[i].indexOf(inputVal) != -1) {
                    this.regCityList.push(searchArray[i])
                    console.log(this.regCityList);
                }
            }
        }
        regListPopup.innerHTML = '';
        regDiv.innerHTML = ''
        regDiv.className = "reg-list"
        regDiv.innerHTML = `<ul class="reg-Ul">${regCityList.map(city => `<li class="reg-cityName" onclick="regCityClick(event)" data-city="${city}">${city.split('|')[1]} ${city.split('|')[2]}</li>`).join('')}</ul>`
        regListPopup.appendChild(regDiv)
    };
  •  点击输入框时,打开城市列表弹窗
    // 打开选择城市弹窗
    function openCityPopup(e) {
        // console.log(e);
        document.getElementById("cityPopup").show()
        if (e.target.dataset.type == "depart") {
            document.getElementById("cityPopup").style.top = "650px"
            document.getElementById("cityPopup").style.left = "-620px"
            this.inputType = "depart"
        } else {
            document.getElementById("cityPopup").style.top = "650px"
            document.getElementById("cityPopup").style.left = "-160px"
            this.inputType = "arrive"
        }
    };
    // 关闭弹窗
    function closeCityPopup(event) {
        const cityPopup = document.getElementById("cityPopup");
        const departCityInput = document.getElementById("departCity");
        const arriveCityInput = document.getElementById("arriveCity");
        // 检查点击是否在弹窗、出发城市输入框或到达城市输入框之外
        if (!cityPopup.contains(event.target) &&
            event.target !== departCityInput &&
            event.target !== arriveCityInput) {
            cityPopup.close();
        }
    };
  • 获取城市分组,首字母分组,地区分组
    // 获取城市分组
    function getListGroup(cityspell) {
        if (cityspell == "热门") { //热门分组
            const allTitle = document.getElementsByClassName("index");
            allTitle[0].style.color = "#499BFC";
            allTitle[0].style.borderBottom = "#499BFC solid 2px";
            allTitle[7].style.color = "#499BFC";
            allTitle[7].style.borderBottom = "#499BFC solid 2px";
            const cityBox = document.querySelector('.city-box');
            cityBox.innerHTML = '';
            const filteredDiv = document.createElement('div');
            filteredDiv.className = 'filtered-cities';
            if (isInter) {
                filteredDiv.innerHTML = `<ul class="filteredBox">${hotCityList.map(city => `<li class="cityName" data-city="${city}" onclick="cityNameClick(event)">${city.split('|')[1]}</li>`).join('')}</ul>`;
            } else {
                filteredDiv.innerHTML = `<ul class="filteredBox">${hotInterList.map(city => `<li class="cityName" data-city="${city}" onclick="cityNameClick(event)">${city.split('|')[1]}</li>`).join('')}</ul>`;
            }
            cityBox.appendChild(filteredDiv);
        } else {
            // 筛选符合条件的城市列表
            let citySpellArray = []
            let interSpellArray = ""
            let filteredCities = [];
            if (this.isInter) {
                citySpellArray = [...cityspell]
                console.log(citySpellArray);
            } else {
                interSpellArray = cityspell
                console.log(interSpellArray);
            }
            const cityBox = document.querySelector('.city-box');
            cityBox.innerHTML = '';
            if (isInter) {
                for (let i = 0; i < citySpellArray.length; i++) {
                    console.log(i);
                    filteredCities = allUserList_Array.filter(city => city.split('|')[0].charAt(0).toUpperCase() == citySpellArray[i])
                    console.log(filteredCities);
                    const spellDiv = document.createElement('div');
                    spellDiv.className = "spell-list";
                    spellDiv.innerHTML = `<p style="margin-bottom:0;">${citySpellArray[i]}</p>`;
                    cityBox.appendChild(spellDiv);
                    let filteredDiv = document.createElement('div');
                    filteredDiv.className = 'filtered-cities';
                    filteredDiv.innerHTML = `<ul class="filteredBox">${filteredCities.map(city => `<li class="cityName" data-city="${city}" onclick="cityNameClick(event)">${city.split('|')[1]}</li>`).join('')}</ul>`;
                    cityBox.appendChild(filteredDiv);
                }
            } else {
                filteredCities = nationalList.filter(city => city.split('|')[4] == interSpellArray)
                let spellDiv = document.createElement('div');
                spellDiv.className = "spell-list";
                spellDiv.innerHTML = `<p style="margin-bottom:0;">${interSpellArray}</p>`;
                cityBox.appendChild(spellDiv);
                let filteredDiv = document.createElement('div');
                filteredDiv.className = 'filtered-cities';
                filteredDiv.innerHTML = `<ul class="filteredBox">${filteredCities.map(city => `<li class="cityName" data-city="${city}" onclick="cityNameClick(event)">${city.split('|')[1]}</li>`).join('')}</ul>`;
                cityBox.appendChild(filteredDiv);
            }

        }
    };
  • 标签切换事件,国际国内切换,首字母切换,地区切换
   // 点击切换国内/国际
    function clickSwitch(event, seq) {
        // console.log(evnet);
        const allSwitch = document.getElementsByClassName("menu");
        console.log(allSwitch);
        for (let i = 0; i < allSwitch.length; i++) {
            if (i == seq) {
                allSwitch[i].style.color = "#499BFC"
                allSwitch[i].style.backgroundColor = "#fff"
                allSwitch[i].style.borderBottom = "#499BFC solid 2px"
            } else {
                allSwitch[i].style.color = "#333"
                allSwitch[i].style.backgroundColor = "#f3f5f7"
                allSwitch[i].style.borderBottom = "none"
            }
        }
        if (allSwitch[seq].innerText == '国内') {
            this.isInter = true
            document.getElementById("indexList").style.display = "flex"
            document.getElementById("interList").style.display = "none"
            this.getListGroup("热门")
        } else {
            this.isInter = false
            document.getElementById("indexList").style.display = "none"
            document.getElementById("interList").style.display = "flex"
            this.getListGroup("热门")
        }
    };

   // 点击标签事件
    function clickTab(event, seq) {
        const allTitle = document.getElementsByClassName("index");
        // 更改选中后的样式
        for (let i = 0; i < allTitle.length; i++) {
            if (i == seq) {
                allTitle[i].style.color = "#499BFC"
                allTitle[i].style.borderBottom = "#499BFC solid 2px"
            } else {
                allTitle[i].style.color = "#333"
                allTitle[i].style.borderBottom = "none"
            }
        }
        this.getListGroup(event.target.dataset.cityspell)
    };
  • 城市名点击事件,搜索列表点击事件、弹出框列表点击事件
    // 城市名称点击事件
    function cityNameClick(event) {
        console.log(this.inputType);
        const cityPopup = document.getElementById("cityPopup");
        if (this.inputType == "depart") {
            document.getElementById("departCity").value = event.target.dataset.city.split('|')[1]
            cityPopup.close()
        } else {
            document.getElementById("arriveCity").value = event.target.dataset.city.split('|')[1]
            cityPopup.close()
        }
    };
    // 城市名称点击事件
    function regCityClick(event) {
        const cityPopup = document.getElementById("cityPopup");
        if (this.inputType == "depart") {
            document.getElementById("departCity").value = event.target.dataset.city.split('|')[1]
            const regListStyle = document.getElementsByClassName("regListPopup")[0]
            regListStyle.style.display = "none"
        } else {
            document.getElementById("arriveCity").value = event.target.dataset.city.split('|')[1]
            const regListStyle = document.getElementsByClassName("regListPopup")[0]
            regListStyle.style.display = "none"
        }
    }
  • 其他
 // 在文档加载完成后添加事件监听器,当点击弹出框外区域时,关闭弹出框
    document.addEventListener("DOMContentLoaded", function () {
        document.addEventListener("click", closeCityPopup);
    });

标签:原生,控件,style,const,city,cityPopup,JS,getElementById,document
From: https://blog.csdn.net/m0_50007683/article/details/141822540

相关文章

  • Nodejs的安装
    一.下载安装包及安装官网下载: (英文)https://nodejs.org/en(中文)https://nodejs.org/zh-cn/nodejs中文网下载: https://nodejs.cn/以上两个地址都可以下载     查询是否安装成功win+R运行cmd,输入node-v查看  二.配置全局安装目......
  • 基于SpringBoot+MySQL+SSM+Vue.js的学生选课系统
    获取见最下方名片获取见最下方名片获取见最下方名片演示视频基于SpringBoot+MySQL+SSM+Vue.js的学生选课系统(附论文)技术描述开发工具:Idea/Eclipse数据库:MySQLJar包仓库:Maven前端框架:Vue/ElementUI后端框架:Spring+SpringMVC+Mybatis+SpringBoot文字描......
  • 云原生周刊:LitmusChaos 审计完成|2024.9.2
    开源项目推荐GardenerGardener实现了Kubernetes集群的自动化管理和操作服务,并提供了一个经过完全验证的可扩展性框架,可以调整以适应任何编程云或基础设施提供商。GrafanaMimirGrafanaMimir为Prometheus提供了横向扩展、高可用、多租户的长期存储解决方案。Terragrunt......
  • jsp班级班费缴纳及使用情况管理56jy4
    jsp班级班费缴纳及使用情况管理56jy4本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表项目功能学生,教师,通知公告,班级信息,班费通知,班费统计,使用情况技术要求:   开发语言:JSP前端使用:HTML5,CSS,JSP动......
  • jsp班级财务管理系统m9ttl
    jsp班级财务管理系统m9ttl本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表项目功能班级信息,学生,教师,班费信息,日常开销开题报告内容一、项目背景与意义在现代化教育体系中,班级作为学校的基本组成单元,其......
  • 【vue、react】前端如何为package.json添加注释
    文章目录前言安装使用方法问题前言写了个项目,想给package.json加注释结果发现加不上去,就在网上查找了相关文章,特意总结记录一下,防止下次使用。参考文章:如何为package.json添加注释众所周知,JSON文件是不支持注释的,除了JSON5/JSONC之外,我们在开发项目特别是前端项目......
  • 借助图形控件Aspose.PSD, 在 Java 中绘制几何形状
    最近,我们使用Aspose.PSDforJava实现了绘制诸如日食和线条等形状的功能。然而,这篇博文将更进一步,向您展示如何在Java中绘制几何形状。幸运的是,您可以使用这个Java绘图库以编程方式执行此操作,因为它是一个完整的包,可以在Java应用程序中处理形状。因此,没有额外的要求,我们可......
  • 一个练习项目,好玩的bbs-nodejs-restify
    代码:varrestify=require('restify')varserver=restify.createServer()constmd5=require('md5');constquerystring=require('querystring');//npminstallrestifyvarsecretKey='saacac3423@21212';varpagesize......
  • 一个练习项目,好玩的bbs-nodejs-fastify
    代码:constfastify=require("fastify")();constmd5=require('md5');constquerystring=require('querystring');//npminstallfastifyvarsecretKey='saacac3423@21212';varpagesize=20;varmysql=req......
  • 云原生存储Rook部署Ceph
            Rook是一款云原生存储编排服务工具,Ceph是一种广泛使用的开源分布式存储方案,通过Rook可以大大简化ceph在Kubernetes集群中的部署和维护工作。        Rook由云原生计算基金会(CNCF)孵化,且于2020年10月正式进入毕业阶段。Rook并不直接提......