首页前端开发JavaScript原生js实现下拉框选择组件

原生js实现下拉框选择组件

时间2024-01-31 16:20:03发布访客分类JavaScript浏览175
导读:收集整理的这篇文章主要介绍了原生js实现下拉框选择组件,觉得挺不错的,现在分享给大家,也给大家做个参考。 本文实例为大家分享了js实现下拉框选择组件的具体代码,供大家参考,具体内容如下功...
收集整理的这篇文章主要介绍了原生js实现下拉框选择组件,觉得挺不错的,现在分享给大家,也给大家做个参考。

本文实例为大家分享了js实现下拉框选择组件的具体代码,供大家参考,具体内容如下

功能需求:

1、点击div后,div显示聚焦状态,同时显示下拉框内容;
2、选择儿童人数后,如果儿童人数大于0,在下方出现对应的儿童年龄选择框数量;
3、成人人数的选择范围是1-7,儿童人数的选择范围是0-4,儿童年龄的选择范围是1、1-17;
4、点击确认按钮后,将选择好的成人人数和儿童人数显示在最上方的div内;
5、可以控制选择框是否可点击;
6、当显示一个ul列表时,点击另一个ul列表,将上一个ul列表隐藏;
7、点击隐藏框内除绑定事件元素外,将正在显示的ul列表隐藏;
8、点击页面中任意空白位置,将显示的下拉框内容整体隐藏;

下拉框不可操作时的显示状态:

下拉框可操作时:

选择儿童人数后,下方自动出现对应数量的儿童年龄选择框:

点击确认按钮后,将结果显示在是上方的div内:

刚开始的想法是对select、ul下拉列表、BTn按钮分别进行事件监听,此外还要有当点击下拉框内其它位置时,ul下拉列表隐藏、当点击body时整个下拉框内容隐藏。监听事件过多,而且事件冒泡也会影响事件的执行,导致某些事件会出现执行多次的情况。

儿童年龄的选择框是根据儿童的人数来生成的,有几个儿童,就有几个年龄选择框。这种情况下,年龄的选择框肯定是动态创建的,无法针对年龄的select进行事件监听,只能采用事件委托的形式,所以最后把对select、ul下拉列表、btn按钮的点击事件,还有当点击container内其它位置时,ul下拉列表隐藏。全部委托给了dropDownContainer元素。

下面附上代码

htML结构代码:

!DOCTYPE html>
    html lang="en">
    head>
      meta charset="UTF-8">
      meta name="viewport" content="width=device-width, inITial-scale=1.0">
      title>
    select/title>
    /head>
    body>
      script type="module">
        import Main From './js/Main.js';
        //参数为false时,选择框不可点击;为true时,选择框可使用    let main=new Main(true);
        main.appendTo("body");
      /script>
    /body>
    /html>
    

Main.js文件:

import Utils from './Utils.js';
export default class Main{
      static styles=false;
      listPRep;
  constructor(state){
        //state控制下拉框是否可点击    this.state=state;
        this.elem=this.createE();
  }
  createE(){
        if(this.elem) return this.elem;
        let div=Utils.createE("div");
        div.classname="guestsNum";
        div.innerHTML=`span>
    人数未定/span>
    i>
    /i>
        div class="dropDownContainer none" id="dropDownContainer">
          div class="dropDownItem clearfix">
            span>
    每间/span>
            div class="dropDownSelect">
              div class="dropDownCont">
    span id="adultNum">
    2 成人/span>
    i>
    /i>
    /div>
              ul class="dropDownList" tag="adult">
${
this.setDropDownList("adult")}
    /ul>
            /div>
            div class="dropDownSelect">
              div class="dropDownCont">
    span id="childrenNum">
    0 儿童/span>
    i>
    /i>
    /div>
              ul class="dropDownList" tag="children">
    li>
    0/li>
${
this.setDropDownList("children")}
    /ul>
            /div>
          /div>
          div class="dropDownItem clearfix none" id="ItemAge">
    /div>
          div class="dropDownBottom clearfix">
        ${
    this.state?'':'em class="dropDownTips">
    请优先选择日期,以便查询实时价格。/em>
'}
        ${
    this.state?'a class="dropDownBtn" id="dropDownBtn" href="javascript:void(0)" rel="external nofollow" rel="external nofollow" >
    确认/a>
    ':'a class="dropDownBtn disabled" href="javascript:void(0)" rel="external nofollow" rel="external nofollow" >
    确认/a>
'}
          /div>
        /div>
    `;
        //设置样式,因为样式只设置一次就好,不需要实例化,所以使用静态方法    Main.setStyles();
        //获取元素    Utils.getIdElem(div,this);
        //监听div的点击事件    div.addEventListener("click",(e)=>
    this.guestsNumClickHandler(e));
        //如果state为true,下拉框监听点击事件    if(this.state) this.dropDownContainer.addEventListener("click",e=>
    this.dropDownContainerClick(e));
        //document监听点击事件,隐藏下拉框    document.addEventListener("click",e=>
    this.documentClick(e));
        return div;
  }
  appendTo(parent){
        Utils.appendTo(this.elem,parent);
  }
  guestsNumClickHandler(e){
        //如果下拉框是显示状态,则直接跳出,避免重复操作    if(!Utils.hasClass(this.dropDownContainer,"none")) return;
        //如果点击的不是guestsNum,直接跳出,避免事件冒泡    if(e.target.nodeName!=="SPAN"&
    &
    e.target.nodeName!=="I"&
    &
    !Utils.hasClass(e.target,"guestsNum")) return;
        //给div添加聚集样式    Utils.addClass(this.elem,"focus");
        //将dropDownContainer显示    Utils.removeClass(this.dropDownContainer,"none");
  }
  dropDownContainerClick(e){
    if(e.target.nodeName==="LI"){
          //点击ul选择列表      this.dropDownListClick(e);
    }
    else if(e.target.id==="dropDownBtn"){
          //点击确认按钮      this.dropDownBtnClick();
    }
    else if(e.target.nodeName==="SPAN" || e.target.nodeName==="I") {
          //点击span或者i标签时,将它们的父元素div作为参数      this.dropDownSelectClick(e.target.parentElement);
    }
    else if(Utils.hasClass(e.target,"dropDownCont")){
          //点击div选择框时,将div作为参数      this.dropDownSelectClick(e.target);
    }
    else {
          //点击下拉框内其它位置时,让当前的ul列表隐藏      if(this.listPrep) this.listPrep.style.display="none";
    }
  }
  dropDownSelectClick(div){
        //隐藏掉上一个显示的ul列表    if(this.listPrep) this.listPrep.style.display="none";
        //当前点击的ul列表赋值给this.listPrep    this.listPrep=div.nextElementSibling;
        //将当前点击的ul列表显示    this.listPrep.style.display="block";
  }
  dropDownListClick(e){
        //获取当前点击的ul的tag属性值    let tag=this.listPrep.getAttribute("tag");
        let unit="";
    switch (tag){
          case "adult": unit="成人";
    break;
          case "children":         unit="儿童";
            let txt=Number(e.target.innerText);
            //根据li的数值,自动创建下面的年龄选择框        this.setDropDownItemAge(txt);
            break;
          case "age": unit="岁";
    break;
    }
        //将选择的li的值,显示出来    this.listPrep.previousElementSibling.FirstElementChild.textContent=e.target.innerText+" "+unit;
        //显示完成后,将当前显示的ul隐藏    this.listPrep.style.display="none";
  }
  setDropDownItemAge(txt){
        let str="span>
    儿童年龄/span>
    ";
    if(txt===0){
          //如果是0,则年龄选择框不显示      this.ItemAge.style.display="none";
    }
else{
          this.ItemAge.style.display="block";
          //循环选择的数值,创建年龄选择框      for(let i=0;
    itxt;
i++){
            str+=`div class="dropDownSelect">
            div class="dropDownCont">
    span>
    1岁/span>
    i>
    /i>
    /div>
            ul class="dropDownList" tag="age">
    li>
    1/li>
${
this.setDropDownList("age")}
    /ul>
          /div>
    `;
      }
          this.ItemAge.innerHTML=str;
    }
  }
  dropDownBtnClick(){
        //将选择的内容显示在最上方的select框内    let resultStr=this.adultNum.innerText.replace(/\s/g,"")+" "+this.childrenNum.innerText.replace(/\s/g,"");
        this.elem.firstElementChild.textContent=resultStr;
        //隐藏dropDownContainer    this.dropDownContainerHide();
  }
  documentClick(e){
        //避免事件冒泡    if(e.target!==document.documentElement &
    &
     e.target!==document.body) return;
        //隐藏dropDownContainer    this.dropDownContainerHide();
  }
  dropDownContainerHide(){
        //div去掉聚集状态    Utils.removeClass(this.elem,"focus");
        //dropDownContainer隐藏    Utils.addClass(this.dropDownContainer,"none");
        //隐藏当前显示的ul列表    if(this.listPrep) this.listPrep.style.display="none";
  }
  setDropDownList(type){
        //创建ul下拉列表内容    let li="";
        let max=0;
    switch (type){
          case "adult": max=8;
    break;
          case "children": max=5;
    break;
          case "age": max=18;
    break;
    }
        for(let i=1;
    imax;
i++){
          li+="li>
    "+i+"/li>
    ";
    }
        return li;
  }
  static setStyles(){
        if(Main.styles) return;
        Main.style=true;
    Utils.insertCss(".guestsNum",{
      width:"108px",      height:"34px",      padding:"0px 12px",      border:"1px solid #ccc",      borderRadius:"3px",      position:"relative",      fontSize:"14px",      color:"#666",      userSelect:"none",    }
)    Utils.insertCss(".guestsNum.focus",{
      borderColor:"#ffa800",      boxShadow:"0 0 4px #ffa800"    }
    )    Utils.insertCss(".guestsNum>
span",{
      lineHeight:"34px"    }
    )    Utils.insertCss(".guestsNum>
i",{
      display:"inline-block",      width:"16px",      height:"16px",      backgroundImage:"url(./image/user.jpg)",      float:"right",      margin:"8px 0px 0px 10px"    }
)    Utils.insertCss(".dropDownContainer",{
      border: "1px solid #ffa800",      borderRadius: "4px",      boxShadow: "0 0 4px #ffa800",      backgroundColor: "#fff",      padding: "20px 15px",      width: "480px",      fontSize:"12px",      position:"absolute",      left:"0px",      top:"35px",    }
)    Utils.insertCss(".dropDownItem",{
      marginBottom:"12px"    }
    )    Utils.insertCss(".dropDownItem>
span",{
      display:"block",      width:"60px",      lineHeight:"28px",      float:"left",    }
)    Utils.insertCss(".dropDownSelect",{
      width:"90px",      height:"30px",      marginRight:"10px",      float:"left",      position:"relative"    }
)    Utils.insertCss(".dropDownCont",{
      border:"1px solid #ccc",      borderRadius:"3px",      height:"12px",      padding:"6px 8px 10px",    }
    )    Utils.insertCss(".dropDownCont>
span",{
      display:"inline-block",      width:"53px",      height:"14px",      lineHeight:"14px",      borderRight:"1px solid #ccc"    }
    )    Utils.insertCss(".dropDownCont>
i",{
      display:"inline-block",      width:"0px",      height:"0px",      border:"5px solid #c6c6c6",      borderColor:"#c6c6c6 transparent transparent",      margin: "6px 0px 0px 4px",      float: "right"    }
)    Utils.insertCss(".dropDownList",{
      listStyle:"none",      padding:"0px",      margin:"0px",      width:"88px",      maxHeight:"200px",      overflow:"auto",      cursor:"pointer",      border:"1px solid #ccc",      backgroundColor:"#fff",      borderRadius:"4px",      position:"absolute",      left:"0px",      top:"30px",      zIndex:"2",      boxShadow: "1px 1px 3px rgba(0,0,0,.1)",      display:"none"    }
    )    Utils.insertCss(".dropDownList>
li",{
      lineHeight:"28px",      paddingLeft:"8px",    }
    )    Utils.insertCss(".dropDownList>
li:hover",{
      background:"#f4f4f4"    }
)    Utils.insertCss(".dropDownBottom",{
      borderTop:"1px solid #ccc",      marginTop:"20px",      paddingTop:"20px"    }
)    Utils.insertCss(".dropDownTips",{
      fontStyle:"normal",      fontSize: "12px",      color: "#ef523d",      lineHeight:"28px"    }
)    Utils.insertCss(".dropDownBtn",{
      textDecoration:"none",      float: "right",      display: "inline-block",      padding: "2px 22px",      backgroundColor: "#ffb200",      borderRadius: "4px",      fontSize: "14px",      lineHeight: "24px",      color: "#fff",    }
)    Utils.insertCss(".dropDownBtn.disabled",{
      backgroundColor: "#efefef",      color: "#999"    }
)    Utils.insertCss(".clearfix:after",{
      content:"\".\"",      display:"block",      overflow:"hidden",      visibility:"hidden",      clear:"both",      height:"0px"    }
)    Utils.insertCss(".none",{
      display:"none"    }
)  }
}
    

Utils.js文件:

export default class Utils{
  static createE(elem,style,prep){
        elem=document.createElement(elem);
        if(style) for(let prop in style) elem.style[prop]=style[prop];
        if(prep) for(let prop in prep) elem[prop]=prep[prop];
        return elem;
  }
  static appendTo(elem,parent){
        if (parent.constructor === String) parent = document.querySelector(parent);
        parent.appendChild(elem);
  }
  static randomNum(min,max){
        return Math.floor(Math.random*(max-min)+min);
  }
  static randomColor(alpha){
        alpha=alpha||Math.random().toFixed(1);
        if(isNaN(alpha)) alpha=1;
        if(alpha>
    1) alpha=1;
        if(alpha0) alpha=0;
        let col="rgba(";
        for(let i=0;
    i3;
i++){
          col+=Utils.randomNum(0,256)+",";
    }
        col+=alpha+")";
        return col;
  }
  static insertCss(select,styles){
    if(document.styleSheets.length===0){
          let styleS=Utils.createE("style");
          Utils.appendTo(styleS,document.head);
    }
        let styleSheet=document.styleSheets[document.styleSheets.length-1];
    let str=select+"{
    ";
    for(VAR prop in styles){
      str+=prop.replace(/[A-Z]/g,function(item){
            return "-"+item.toLocaleLowerCase();
      }
    )+":"+styles[prop]+";
    ";
    }
    str+="}
    "    styleSheet.insertRule(str,styleSheet.cssRules.length);
  }
  static getIdElem(elem,obj){
        if(elem.id) obj[elem.id]=elem;
        if(elem.children.length===0) return obj;
        for(let i=0;
    ielem.children.length;
i++){
          Utils.getIdElem(elem.children[i],obj);
    }
  }
  static addClass(elem,className){
        let arr=(elem.className+" "+className).match(/\S+/g);
        arr=arr.filter((item,index)=>
    arr.indexOf(item,index+1)0)    elem.className=arr.join(" ");
  }
  static removeClass(elem,className){
        if(!elem.className) return;
        let arr=elem.className.match(/\S+/g);
        let arr1=className.match(/\S+/g);
        arr1.foreach(item=>
{
          arr=arr.filter(t=>
t!==item)    }
    )    elem.className=arr.join(" ");
  }
  static hasClass(elem,className){
        if(!elem.className) return false;
        let arr=elem.className.match(/\S+/g);
        let arr1=className.match(/\S+/g);
        let res;
        arr1.forEach(item=>
{
          res= arr.some(it=>
it===item)    }
    )    return res;
  }
}
    

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

您可能感兴趣的文章:
  • vuejs实现下拉框菜单选择
  • js实现select下拉框选择
  • javascript实现日期三级联动下拉框选择菜单
  • js实现可输入可选择的select下拉框
  • JavaScript实现单击下拉框选择直接跳转页面的方法
  • js实现下拉框选择要显示图片的方法

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!

上一篇: 原生js实现滑块区间组件下一篇:原生js实现自定义滚动条组件猜你在找的JavaScript相关文章 html font标签如何设置字体大小?html font标签属性用法介绍2022-05-16vue3+TypeScript+vue-router的使用方法2022-04-16vue3获取当前路由地址2022-04-16如何利用React实现图片识别App2022-04-16JavaScript展开运算符和剩余运算符的区别详解2022-04-16微信小程序中使用vant框架的具体步骤2022-04-16Vue elementUI表单嵌套表格并对每行进行校验详解2022-04-16如何利用Typescript封装本地存储2022-04-16微信小程序中wxs文件的一些妙用分享2022-04-16JavaScript的Set数据结构详解2022-04-16 其他相关热搜词更多phpjavapython程序员loadpost-format-gallery

若转载请注明出处: 原生js实现下拉框选择组件
本文地址: https://pptw.com/jishu/594192.html
C语言中数组元素的下标下限是什么 c语言return的用法是什么?

游客 回复需填写必要信息