This article example shares the specific code of js to implement the drop-down box selection component for your reference. The specific content is as follows Functional requirements: 1. After clicking div, div shows the focus state and the drop-down box content is displayed at the same time; Display status when the drop-down box is inoperable: When the drop-down box is operable: After selecting the number of children, the corresponding number of child age selection boxes will automatically appear below: After clicking the confirmation button, the result is displayed in the div above: The initial idea was to monitor events for the select, ul drop-down list, and btn button respectively. In addition, when other positions in the drop-down box are clicked, the ul drop-down list is hidden, and when the body is clicked, the entire drop-down box content is hidden. There are too many monitoring events, and event bubbling will also affect the execution of events, causing some events to be executed multiple times. The selection box for children's ages is generated based on the number of children. There are as many age selection boxes as there are children. In this case, the age selection box must be created dynamically, and it is impossible to listen to events for the age selection. Only event delegation can be used. Therefore, the click events of the select, ul drop-down list, btn button, and when other positions in the container are clicked, the ul drop-down list is hidden. All delegated to the dropDownContainer element. Attach the code below HTML structure code: <!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'; //When the parameter is false, the selection box cannot be clicked; when it is true, the selection box can be used. let main=new Main(true); main.appendTo("body"); </script> </body> </html> Main.js file: import Utils from './Utils.js'; export default class Main{ static styles=false; listPrep; constructor(state){ //state controls whether the drop-down box is clickable 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>Number of people is undetermined</span><i></i> <div class="dropDownContainer none" id="dropDownContainer"> <div class="dropDownItem clearfix"> <span>Each</span> <div class="dropDownSelect"> <div class="dropDownCont"><span id="adultNum">2 Adult</span><i></i></div> <ul class="dropDownList" tag="adult">${this.setDropDownList("adult")}</ul> </div> <div class="dropDownSelect"> <div class="dropDownCont"><span id="childrenNum">0 children</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">Please select the date first so that you can check the real-time price. </em>'} ${this.state?'<a class="dropDownBtn" id="dropDownBtn" href="javascript:void(0)" rel="external nofollow" rel="external nofollow" >Confirm</a>':'<a class="dropDownBtn disabled" href="javascript:void(0)" rel="external nofollow" rel="external nofollow" >Confirm</a>'} </div> </div>`; //Set the style. Because the style only needs to be set once and does not need to be instantiated, the static method Main.setStyles() is used; //Get the element Utils.getIdElem(div,this); //Listen for div's click event div.addEventListener("click",(e)=>this.guestsNumClickHandler(e)); //If state is true, the drop-down box listens for click events if(this.state) this.dropDownContainer.addEventListener("click",e=>this.dropDownContainerClick(e)); //document listens for click events and hides the drop-down boxdocument.addEventListener("click",e=>this.documentClick(e)); return div; } appendTo(parent){ Utils.appendTo(this.elem,parent); } guestsNumClickHandler(e){ //If the drop-down box is in display state, jump out directly to avoid repeated operations if(!Utils.hasClass(this.dropDownContainer,"none")) return; //If guestsNum is not clicked, jump out directly to avoid event bubbling if(e.target.nodeName!=="SPAN"&&e.target.nodeName!=="I"&&!Utils.hasClass(e.target,"guestsNum")) return; //Add focus style to div Utils.addClass(this.elem,"focus"); //Display the dropDownContainer Utils.removeClass(this.dropDownContainer,"none"); } dropDownContainerClick(e){ if(e.target.nodeName==="LI"){ //Click on ul to select the list this.dropDownListClick(e); } else if(e.target.id==="dropDownBtn"){ //Click the confirm button this.dropDownBtnClick(); } else if(e.target.nodeName==="SPAN" || e.target.nodeName==="I") { //When clicking the span or i tag, take their parent element div as parameter this.dropDownSelectClick(e.target.parentElement); } else if(Utils.hasClass(e.target,"dropDownCont")){ //When clicking the div selection box, use div as a parameter this.dropDownSelectClick(e.target); } else { //When clicking other positions in the drop-down box, hide the current ul list if(this.listPrep) this.listPrep.style.display="none"; } } dropDownSelectClick(div){ //Hide the last displayed ul list if(this.listPrep) this.listPrep.style.display="none"; //The currently clicked ul list is assigned to this.listPrep this.listPrep=div.nextElementSibling; //Display the currently clicked ul list this.listPrep.style.display="block"; } dropDownListClick(e){ //Get the tag attribute value of the currently clicked ul let tag=this.listPrep.getAttribute("tag"); let unit=""; switch (tag){ case "adult": unit="Adult";break; case "children": unit="children"; let txt=Number(e.target.innerText); //According to the value of li, automatically create the age selection box below this.setDropDownItemAge(txt); break; case "age": unit="years old";break; } //Display the value of the selected li this.listPrep.previousElementSibling.firstElementChild.textContent=e.target.innerText+" "+unit; //After display is completed, hide the currently displayed ul this.listPrep.style.display="none"; } setDropDownItemAge(txt){ let str="<span>Child's Age</span>"; if(txt===0){ //If it is 0, the age selection box will not be displayed this.ItemAge.style.display="none"; }else{ this.ItemAge.style.display="block"; //Loop through the selected values and create an age selection box for(let i=0;i<txt;i++){ str+=`<div class="dropDownSelect"> <div class="dropDownCont"><span><1 year old</span><i></i></div> <ul class="dropDownList" tag="age"><li><1</li>${this.setDropDownList("age")}</ul> </div>`; } this.ItemAge.innerHTML=str; } } dropDownBtnClick(){ //Display the selected content in the select box at the top let resultStr=this.adultNum.innerText.replace(/\s/g,"")+" "+this.childrenNum.innerText.replace(/\s/g,""); this.elem.firstElementChild.textContent=resultStr; //Hide dropDownContainer this.dropDownContainerHide(); } documentClick(e){ //Avoid event bubblingif(e.target!==document.documentElement && e.target!==document.body) return; //Hide dropDownContainer this.dropDownContainerHide(); } dropDownContainerHide(){ //div removes the aggregation state Utils.removeClass(this.elem,"focus"); //dropDownContainer hides Utils.addClass(this.dropDownContainer,"none"); //Hide the currently displayed ul list if(this.listPrep) this.listPrep.style.display="none"; } setDropDownList(type){ //Create ul drop-down list content 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;i<max;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 file: 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(alpha<0) alpha=0; let col="rgba("; for(let i=0;i<3;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(/[AZ]/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;i<elem.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; } } The above is the full content of this article. I hope it will be helpful for everyone’s study. I also hope that everyone will support 123WORDPRESS.COM. You may also be interested in:
|
<<: Detailed steps for Navicat to remotely connect to SQL Server and convert to MySQL
>>: In-depth explanation of special permissions SUID, SGID and SBIT in Linux
1. Title HTML defines six <h> tags: <h1&...
Due to the advantages of GTID, we need to change ...
Table of contents 1. What is a trigger? 2. Create...
One trick for dealing with this type of error is t...
What is a selector? The role of the selector is t...
Preface I always thought that UTF-8 was a univers...
K8s k8s is a cluster. There are multiple Namespac...
Installation environment: CentOS7 64-bit MINI ver...
There are two ways to deploy Angular projects wit...
Specific method: 1. Open Command Prompt 2. Enter ...
This article describes how to configure time sync...
MVCC MVCC (Multi-Version Concurrency Control) is ...
Table of contents 1. Commonjs exports and require...
By understanding how tomcat handles concurrent re...
Basic syntax of the table <table>...</tab...