原生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实现下拉框选择组件
本文地址: https://pptw.com/jishu/594192.html
