Implementation steps of js object-oriented encapsulation cascading drop-down menu list

Implementation steps of js object-oriented encapsulation cascading drop-down menu list

The cascading drop-down menu developed in this example is a DOM element created based on existing JSON data. After clicking the text box, a first-level menu is displayed. If a menu contains submenus, there will be an arrow to the right of the menu indicating this. After clicking the menu, the next level menu will be displayed, and so on. When there is no submenu under the menu, it will be displayed in the text box after selecting the menu.

The effect of the cascading menu after opening is as shown in the figure:

Using the plug-in packaged in the example, you only need an input element to automatically generate a cascading drop-down menu through the plug-in. The HTML code is as follows:

 <div style="margin-top:100px;text-align:center;">
  <input type="text" id="input">
 </div>

Next, let's see how to implement the specific encapsulated js code.

1. Declare the constructor of the cascading menu

The constructor needs to pass in two parameters: a text box element and menu associated data.

 //elem is a text box, data is menu-related data function CascadeMenu(elem,data){

 }

2. Create cascading menu related elements in the constructor and put them on the page. The specific code is as follows:

function CascadeMenu(elem,data){
  //Get the text box this.eInput = elem;
  //Set the text box to read-only this.eInput.setAttribute('readonly',true);
  //Set the text box prompt this.eInput.placeholder = 'Please select';
  //Get the parent element of the text box var eInputParent = this.eInput.parentNode;
  //Create a cascading menu container this.eCascade = document.createElement('div');
  this.eCascade.className = 'cascade_container';
  //Create a menu drop-down list container this.eCascadeInto = document.createElement('div');
  this.eCascadeInto.className = 'cascade_into';
  //The drop-down list container is hidden by default this.eCascadeInto.style.display = 'none';
  //Put each element into the page this.eCascade.appendChild(this.eInput);
  this.eCascade.appendChild(this.eCascadeInto);
  eInputParent.appendChild(this.eCascade);
  //Get menu data this.aData = data;
  //Record the selected menu data this.aSelected = [];
  //Menu open state, default is false, means hidden this.bShow = false;
 }

3. Bind click events to text boxes to generate cascading drop-down menus

Now that you have placed all the required elements on the page, you can show and hide the cascading menu elements by clicking the text box;
When displaying a cascading menu element, the cascading drop-down menu should be generated by data.
Because each click needs to be generated, you can add a method to the constructor's prototype. As shown below:

function CascadeMenu(elem,data){
  /*…*/

  this.eInput.addEventListener('click',()=>{
   //Judge the menu opening status if(this.bShow){ 
    //If it is open, hide the menu this.eCascadeInto.style.display = 'none';
    //Modify the menu opening status this.bShow = false;
   }else{
    //Display cascade menu elements this.eCascadeInto.style.display = 'none';
    //Save the selected menu data this.aSelected = this.eInput.value.split('>');
    //Generate cascading menu this.generateMenu();
   }
  });
 }
 //Generate cascading menu based on dataCascadeMenu.prototype.generateMenu = function(){
  //When calling the instance object in fnCreatHTML, you need to declare a variable pointing to this
  var _self = this;
  //Because we are not sure how many groups of submenus there are, we need to declare a function to call recursively //data: incoming data, step: current level function fnCreatHTML(data,step){
   //Used to store submenu data var aChildArr = null;
   //Generate menu DOM string var sHTML = '<ul>';
   //Loop data for(let i=0;i<data.length;i++){
    //Judge if there is a submenu and add the child class to display the arrow on the right side of the menu if (data[i].child) { 
     //Judge whether it is the current selection. If so, add cur class and store submenu data if(data[i].name==this.aSelected[step]){
      aChildArr = data[i].child;
      sHTML += '<li class="child cur" data-po="'+step+'">';
     }else{
      sHTML += '<li class="child" data-po="'+step+'">';
     }
    }else{ 
     //If there is no submenu, add it directly to the menu list sHTML += data[i].name == this.aSelected[step]?
                  '<li class="cur" data-po="'+step+'">':
                  '<li data-po="'+step+'">';
    }
    //Add menu name sHTML += data[i].name;
    //End the current menu sHTML += '</li>';
   }
   sHTML += '</ul>';
   //If multiple menus are selected, recursively call the function to generate submenus if(this.aSelected.length>step+1){
    sHTML += fnCreateHTML(aChildArr,step+1);
   }
   return sHTML;
  }
  this.eCascadeInto.innerHTML = fnCreatHTML(this.aData,0);
 }

4. Bind events on the menu to select the menu

There are two types of cascading menus: one with a sub-menu that is displayed when clicked;
One type has no sub-menus. When clicked, the menu is directly selected and the selected menu is displayed in the text box by level. The code looks like this:

function CascadeMenu(elem,data){
  /*…*/

  //Use event delegation to select the menu this.eCascadeInto.addEventListener('click',(event)=>{
   //Get the menu var eTarget = event.target;
   //Get the selected level var po = +eTarget.dataset.po;
   //Delete the data after the current selection level this.aSelected.splice(po+1,this.aSelected.length-(po+1));
   //Modify the current selected data this.aSelected[po] = eTarget.innerHTML;
   //Judge whether there is a submenu if(eTarget.className.indexOf('child')==-1){ //If there is no submenu, select directly this.eInput.value = this.aSelected.join('>');
    this.eCascadeInto.style.display = 'none';
    this.bShow = false;
   }else{ //If there is a submenu, display the next level. //Regenerate the DOM element and add an empty string to the array to display the next level. this.aSelected.push('')
    //Regenerate the cascading menu this.generateMenu();
   }  
  });
 }

5. Hide the menu when clicking on a blank area of ​​the page

Now you can only show and hide the menu by clicking on the text box. Generally speaking, any open pop-up window is expected to be closed outside the pop-up window. This requires modifying the click event function on the text box: when opening the menu, bind the click event on the document element to close the menu; when hiding the menu, cancel the click event bound to the document. As shown below:

function CascadeMenu(elem,data){
  /*…*/

  this.eInput.addEventListener('click',()=>{
   //Judge the menu opening status if(this.bShow){ 
    //If it is open, hide the menu this.eCascadeInto.style.display = 'none';
    //Modify the menu opening status this.bShow = false;
    //Cancel the event on document document.onclick = null;
   }else{
    //Display cascade menu elements this.eCascadeInto.style.display = 'none';
    //Save the selected menu data this.aSelected = this.eInput.value.split('>');
    //Generate cascading menu this.generateMenu();
    document.onclick = () => {
     //Hide the menu this.eCascadeInto.style.display = 'none';
     //Modify the menu opening status this.bShow = false;
     //Cancel the event on document document.onclick = null;
    }
   }
  });
  //Prevent bubbling this.eCascade.addEventListener('click',(event)=>{
   event.stopPropagation();
  });

  /*…*/
 }

6. Finally, prepare the data, call the constructor, and generate a cascading drop-down menu as shown below:

var json = [
  {
   "name":"北京","id":"110000","child":[
    {"name":"city district","id":"110100","child":[
     : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
    },
    {"name":"北京","id":"110000","child":null}
   ]
  },
  {
   "name":"Hebei Province","id":"130000","child":[
    {"name":"Shijiazhuang City","id":"130100","child":[
     : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
    },
    {"name":"Tangshan City","id":"130200","child":[
     : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
    },
    {"name":"Qinhuangdao City","id":"130300","child":[
     {"name":"Municipal District","id":"130301","child":null},{"name":"Haigang District","id":"130302","child":null},{"name":"Shanhaiguan District","id":"130303","child":null},{"name":"Beidaihe District","id":"130304","child":null},{"name":"Funing District","id":"130306","child":null},{"name":"Qinglong Manchu Autonomous County","id":"130321","child":null},{"name":"Changli County","id":"130322","child":null},{"name":"Lulong County","id":"130324","child":null}]
    },
    {"name":"Handan City","id":"130400","child":[
     : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
    }
   ]
  },
  {
   "name":"Hunan Province","id":"430000","child":[
    {"name":"Changsha City","id":"430100","child":[
     : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
    },
    {"name":"Zhuzhou City","id":"430200","child":[
     : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
    },
    {"name":"Xiangtan City","id":"430300","child":[
     {"name":"District","id":"430301","child":null},{"name":"Yuhu District","id":"430302","child":null},{"name":"Yuetang District","id":"430304","child":null},{"name":"Xiangtan County","id":"430321","child":null},{"name":"Xiangxiang City","id":"430381","child":null},{"name":"Shaoshan City","id":"430382","child":null}]
    },
    {"name":"Hengyang City","id":"430400","child":[
     {"name":"Districts under the jurisdiction of the city","id":"430401","child":null},{"name":"Zhuhui District","id":"430405","child":null},{"name":"Yanfeng District","id":"430406","child":null},{"name":"Shigu District","id":"430407","child":null},{"name":"Zhengxiang District","id":"430408","child":null},{"name":"Nanyue District","id":"430412","child":null},{"name":"Hengyang County","id":"430421","child":null},{"name":"Hengnan County","id":"430422","child":[
      {"name":"Santang Town",id:"430422",child:null},{"name":"Chejiang Town",id:"430422",child:null}
     ]},{"name":"Hengshan County","id":"430423","child":null},{"name":"Hengdong County","id":"430424","child":null},{"name":"Qidong County","id":"430426","child":null},{"name":"Leiyang City","id":"430481","child":null},{"name":"Changning City","id":"430482","child":null}]
    }
   ]
  },
  {
   "name":"Guangdong Province","id":"440000","child":[
    {"name":"Guangzhou","id":"440100","child":[
     : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
    },
    {"name":"Shaoguan City","id":"440200","child":[
     : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
    },
    {"name":"深圳","id":"440300","child":[
     {"name":"District","id":"440301","child":null},{"name":"Luohu District","id":"440303","child":null},{"name":"Futian District","id":"440304","child":null},{"name":"Nanshan District","id":"440305","child":null},{"name":"Baoan District","id":"440306","child":null},{"name":"Longgang District","id":"440307","child":null},{"name":"Yantian District","id":"440308","child":null}]
    },
    {"name":"Zhuhai City","id":"440400","child":[
     {"name":"District","id":"440401","child":null},{"name":"Xiangzhou District","id":"440402","child":null},{"name":"Doumen District","id":"440403","child":null},{"name":"Jinwan District","id":"440404","child":null}]
    }
   ]
  },
  {
   "name":"Nansha Islands","id":"900001","child":null
  }
 ];

 var eText = document.getElementById('input');
 new CascadeMenu(eText,json);

A packaged js cascade drop-down function is completed, and you can write your own CSS style according to the picture to achieve the desired effect.

The above is the detailed content of the implementation steps of js object-oriented encapsulation cascading drop-down menu list. For more information about js encapsulation drop-down menu, please pay attention to other related articles on 123WORDPRESS.COM!

You may also be interested in:
  • Implementing HTML navigation bar drop-down menu with JavaScript
  • JavaScript to achieve the effect of web page drop-down menu
  • Detailed explanation of how to use the Vue.js drop-down menu component
  • js drop-down menu clicks next to collapse implementation (pitfall record)
  • A brief discussion on how to implement custom drop-down menu instructions in Vue.js
  • js realizes the effect of button switch stand-alone drop-down menu
  • js dynamically sets the default selected item in the select drop-down menu
  • Pure JS to achieve the birth date [year, month, day] drop-down menu effect
  • JS implements an example of clicking the drop-down menu to synchronize the selected content to the input box
  • js prevents the default right-click drop-down menu method

<<:  MySQL-group-replication configuration steps (recommended)

>>:  Detailed description of nginx from compilation and installation to configuration file description in Chinese

Recommend

HTML table tag tutorial (13): internal border style attributes RULES

RULES can be used to control the style of the int...

MySQL database rename fast and safe method (3 kinds)

Table of contents How to rename MySQL database Th...

Detailed explanation of JavaScript to monitor route changes

Table of contents history pushState() Method push...

Detailed process of installing various software in Docker under Windows

1. Install MySQL # Download mysql in docker docke...

How does MySQL achieve master-slave synchronization?

Master-slave synchronization, also called master-...

MySQL SQL statement performance tuning simple example

MySQL SQL statement performance tuning simple exa...

JavaScript's unreliable undefined

undefined In JavaScript, if we want to determine ...

JavaScript implementation of magnifying glass details

Table of contents 1. Rendering 2. Implementation ...

MySQL master-slave replication principle and practice detailed explanation

Table of contents Introduction effect principle f...

Pure CSS3 realizes the effect of div entering and exiting in order

This article mainly introduces the effect of div ...

Summary of 7 pitfalls when using react

Table of contents 1. Component bloat 2. Change th...

CSS imitates Apple's smooth switch button effect

Table of contents 1. Code analysis 2. Source code...