Idée : chaque menu déroulant, en tant que composant, peut recevoir un ensemble de données et générer différentes options de menu basées sur différents contenus de données. La corrélation entre les trois niveaux est obtenue grâce au lancer d'événements. Les données sont obtenues à partir de l'arrière-plan.
Lorsque vous cliquez sur le menu de la province pour sélectionner Shaanxi, le composant du menu supprimera la province actuelle via le lancement d'événements. Après avoir connu la province, vous pouvez obtenir les données de la ville sous la province en arrière-plan. Et ainsi de suite.
Effet de réalisation :
## URL : http://10.9.72.245:4010
## Méthode : "GET"
## Format de données :
Requête : QueryString
Réponse :JSON
1. http: //10.9.72.245:4010/getProvince
2. http://10.9.72.245:4010/getCity 3. http://10.9.72.245:4010/getCounty
nom de l'interface de la province : /getProvince
Request
: Aucun paramètre
Réponse : { "province":["Beijing","Tianjin","Hebei",...]}
nom de l'interface :/getCity
requête :?province="Hebei"
réponse : {"ville ":["Shijiazhuang", "Tangshan", "Qinhuangdao",...]}
nom de l'interface : /getCounty
requête : ?city="Shijiazhuang"
réponse : {"county":["Chang'an District ", "Qiaodong District", "Qiaoxi District",...]}
<!DOCTYPE html> <html> <tête> <méta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <titre>Document</titre> </tête> <corps> <type de script="module"> importer QueryString depuis './js/QueryString.js' ; importer DropDownMemu depuis './js/DropDownMemu.js' ; laissez cityInfo = {} ; init(); fonction init(){ ajax("http://10.9.72.245:4010","getProvince").then(successFunction).catch(failFunction); } //Exécuter après une communication ajax réussie : fonction succèsFonction(_data){ let data = JSON.parse(_data); let key = Object.keys(data)[0]; données = Objet.values(données)[0]; if(DropDownMemu.Obj[clé]){ DropDownMemu.Obj[key].list = data; DropDownMemu.Obj[key].name = data[0]; }autre{ let memu = new DropDownMemu(clé); memu.addEventListener("change",changeHandler); memu.list = données ; memu.name =données[0]; memu.appendTo("corps"); cityInfo[clé] = données[0]; } } // Lorsque le contenu de l'affichage du menu change, recevez l'événement lancé par le menu et obtenez les informations contenues dans l'événement, telles que {"province": "Shaanxi"} ou {"city": "Xi'an"} fonction changeHandler(e){ let key = e.currentTarget.label; cityInfo[clé] = e.data[clé]; laissez interfaceName; si(e.data.province){ interfaceName = "getCity" ; }sinon si(e.data.city){ interfaceName = "getCounty" ; }autre{ retour } ajax("http://10.9.72.245:4010",interfaceName,cityInfo).then(successeFunction).catch(failFunction); } /* communication ajax : Liste des paramètres : url : adresse du service en arrière-plan. interfaceType : type d'interface, tel que "getProvince" data : données transmises, par exemple : {"province": "Shaanxi"} Type de communication : demande "GET" par défaut si les données doivent être envoyées au format json : la valeur par défaut est false */ fonction ajax(url,interfaceType,data,type="get",json=false){ type = type.toUpperCase(); let o = type==="GET" ? null : données ; si(données) données = json ? JSON.stringify(données) : QueryString.stringify(données); sinon données = "" ; renvoyer une nouvelle promesse (fonction (résoudre, rejeter) { laissez xhr = new XMLHttpRequest(); xhr.open(type,url + "/" + interfaceType + (type==="GET"? "?"+data : "")); xhr.send(o); xhr.onreadystatechange = fonction(){ si(xhr.readyState===4 && xhr.status===200){ résoudre (xhr.response); }sinon si(xhr.readyState===4){ résoudre (xhr.status); } } xhr.onerror= fonction(){ rejeter (xhr.response); } }) } //Exécuter la fonction failFunction(_err){ lorsque la communication ajax échoue console.log(_err); } </script> </corps> </html>
composant d'importation de classe DropDownMemu depuis "./Component.js" ; exporter la classe par défaut DropDownMemu étend le composant { _list; // Options actuelles du menu déroulant. _name; //Le nom actuellement sélectionné à afficher, par exemple : "Pékin" label; //L'étiquette du menu déroulant actuel, province ville comté spanLabel; // Conteneur d'étiquettes spanCaret; // Triangle ul; // Conteneur d'options déroulantes bool=false; // Contrôle les événements de la souris, l'état du focus ou la sélection, ne déclenche pas l'effet de glissement d'entrée et de sortie de la souris. //Définissez le style du menu déroulant en fonction des différents états. statique DROPDOWN = Symbole (); statique PAR DÉFAUT = Symbole (); // Les variables globales statiques sont stockées dans cet objet à chaque fois qu'un menu déroulant est créé, et chaque menu déroulant créé est géré globalement. Obj statique = {} ; constructeur (_label) { super("p"); this.label = _label; //Créer une structure HTML this.render(); //Définit le style this.setStyle(); // La souris glisse vers l'intérieur et l'extérieur et clique, le focus est flou, l'événement de clic this.elem.addEventListener("focusin", e =>this.mouseHandler(e)); this.elem.addEventListener("focusout", e =>this.mouseHandler(e)); this.elem.addEventListener("mouseenter", e=>this.mouseHandler(e)); this.elem.addEventListener("mouseleave", e=>this.mouseHandler(e)); this.elem.addEventListener("click", e => this.mouseHandler(e)); } gestionnaire de souris(e){ commutateur (e.type) { cas "mouseenter": si (this.bool) retourne this.elem.style.backgroundColor = "#e6e6e6"; casser; cas "mouseleave": si (this.bool) retourne this.elem.style.backgroundColor = "#fff"; casser; cas "focusin": this.setState(DropDownMemu.DROPDOWN); this.bool = vrai ; casser; cas "focusout": this.setState(DropDownMemu.DEFAULT); this.bool = faux ; cas "clic" : if(e.target.constructor !== HTMLLIElement) return this._name = e.target.textContent ; // Modifie le contenu actuellement affiché lorsque vous cliquez dessus, réinitialise le style et lance des événements pour informer le monde extérieur du contenu actuel. this.setContent(); let evt = new FocusEvent("focusout"); this.elem.dispatchEvent(evt); } } définir le nom(_name){ this._name = _name; this.setContent(); } obtenir le nom(){ renvoie this._name ; } définir la liste (_list) { this._list = _list; this.ul.innerHTML = ""; this.ul.appendChild(this.createLi()); } // Modifier le contenu actuellement affiché du menu et lancer data setContent(_name){ this._name = _name || this.spanLabel.textContent = this._name; let evt = new MouseEvent("change"); si(!evt.data) evt.data = {} evt.data[this.label] = this._name; this.dispatchEvent(evt); } //Créez une option de menu déroulant basée sur la liste spécifiée. créerLi(_list){ this._list = _list || this._list; laissez elem = document.createDocumentFragment(); this._list.forEach((élément, index) => { let li = document.createElement("li"); li.textContent = élément ; Objet.assign(li.style, { hauteur de la ligne : "26px", remplissage : "0 15px", }) elem.appendChild(li); }) renvoyer l'élément ; } setState(type){ commutateur (type) { cas DropDownMemu.DROPDOWN : this.elem.style.backgroundColor = "#e6e6e6"; this.ul.style.display = "bloquer" ; casser; cas DropDownMemu.DEFAULT : this.elem.style.backgroundColor = "#fff"; this.ul.style.display = "aucun" ; casser; } } appendTo(parent){ super.appendTo(parent); DropDownMemu.Obj[this.label] = ceci ; } rendre() { this.elem.setAttribute("tabIndex",1); this.spanLabel = document.createElement("span"); this.spanCaret = document.createElement("span"); this.ul = document.createElement("ul"); this.elem.appendChild(this.ul); this.spanLabel.textContent = this._name; this.elem.appendChild(this.spanLabel); this.elem.appendChild(this.spanCaret); } setStyle() { Objet.assign(this.elem.style, { float : "gauche", minHauteur : "20px", largeur min : "80px", couleur : "#333", fontWeight : "normal", textAlign : "centre", espace blanc : "maintenant", verticalAlign : "milieu", curseur : "pointeur", bordure : "1px solide #ccc", borderRadius : "4px", Couleur d'arrière-plan : "#fff", remplissage : "6px 12px", Taille de la police : "14px", userSelect : "aucun", marginRight : "100px", position : "relative", }); Objet.assign(this.spanLabel.style, { float : "gauche", remplissage : "0 5px" }) Objet.assign(this.spanCaret.style, { affichage : "bloc-en-ligne", verticalAlign : "milieu", borderTop : "4px en pointillés", borderRight : "4px solide transparent", borderLeft : "4px solide transparent", }) Objet.assign(this.ul.style, { style de liste : "aucun", position : "absolue", en haut : "100%", à gauche : "0", zIndice : "1000", largeur min : "100px", remplissage : "5px 0px", marge : "2px 0 0", Taille de la police : "14px", textAlign : "gauche", Couleur d'arrière-plan : "#fff", bordure : "1px solide rgba(0, 0, 0, 0.15)", borderRadius : "4px", boxShadow : "0 6px 12px rgba(0, 0, 0, 0,175)", affichage : "aucun", }) } }
exporter la classe par défaut. Le composant étend EventTarget{ élément; constructeur (_type) { super(); this.elem = this.createElem(_type); } créerElem(_type){ laissez elem = document.createElement(_type); renvoyer l'élément ; } appendTo(parent){ if(typeof parent==="string") parent = document.querySelector(parent); parent.appendChild(this.elem); } }
let http = require("http"); let querystring = require("querystring"); laissez les données, demande, res; // Lit toutes les données de la ville, les analyse en objets, et les lit de manière synchrone. laissez fs = require("fs"); laissez allCityInfo = JSON.parse(fs.readFileSync('./city.json')); laissez serveur = http.createServer(listenerHandler); server.listen(4010,"10.9.72.245",listenerDoneHandler); fonction écouteurHandler(_req,_res){ req = _req; res = _res; res.writeHead(200,{ "content-type": "text/html; charset = utf-8", "Contrôle d'accès-Autoriser-Origine": "*", "Contrôle d'accès-Autoriser-En-têtes": "*", }); données=""; req.on("données",fonction(_data){ données=_données ; }) req.on("end",receiveHandler); } fonction recevoirHandler(){ // console.log(allCityInfo); // Analyse le type d'interface en fonction de l'url de l'en-tête de la requête let type = req.url.trim().split("?")[0].replace(///g,""); console.log(type); // Analyse les paramètres entrants en fonction de l'url de l'en-tête de la requête if(req.method.toUpperCase()==="GET"){ if(req.url.includes("favicon.ico")) return res.end(); sinon data = req.url.includes("?") ? req.url.split("?")[1] : ""; } essayer{ données = JSON.parse(données); }attraper{ data = querystring.parse(data); } console.log(données); //Recherche des données en fonction du type d'interface. laissez la liste = {} ; commutateur (type) { cas "getProvince": list.province = Object.keys(allCityInfo); casser; cas "getCity" : list.city = Object.keys(allCityInfo[data.province]); casser; cas "getCounty": list.county = allCityInfo[data.province][data.city]; casser; } console.log(liste); res.write(JSON.stringify(list)); res.end() } fonction écouteurDoneHandler(){ console.log("Le service a démarré avec succès"); }
{
"Pékin": {
"Pékin": ["District de Dongcheng", "District de Xicheng", "District de Chongwen", "District de Xuanwu", "District de Chaoyang", "District de Fengtai", "District de Shijingshan", "District de Haidian", "District de Mentougou", « District de Fangshan », « District de Tongzhou », « District de Shunyi », « District de Changping », « District de Daxing », « District de Pinggu », « District de Huairou », « Comté de Miyun », « Comté de Yanqing », « Autres »]
} ,
"Tianjin": {
"Tianjin": ["District de Heping", "District de Hedong", "District de Hexi", "District de Nankai", "District de Hebei", "District de Hongjiao", "Nouveau district de Binhai", "District de Dongli", "District de Xiqing" "District de Jinnan", "District de Beichen", "District de Ninghe", "District de Wuqing", "Comté de Jinghai", "District de Baodi", "Jixian", "District de Tanggu", "District de Hangu", " District de Dagang ", "Baodi District", "Autres"]
},
}
Ce qui précède est une explication détaillée du menu de liaison à trois niveaux utilisant JS (avec explication des idées). Pour plus d'informations, veuillez prêter attention aux autres articles connexes sur PHP Site chinois !