Ideia: Cada menu suspenso, como componente, pode receber um conjunto de dados e gerar diferentes opções de menu com base em diferentes conteúdos de dados. A correlação entre os três níveis é alcançada através do lançamento de eventos. Os dados são obtidos em segundo plano.
Ao clicar no menu da província para selecionar Shaanxi, o componente do menu descartará a província atual por meio do lançamento de eventos. Depois de conhecer a província, você pode obter os dados da cidade sob a província em segundo plano. E assim por diante.
Efeito de realização:
## URL: http://10.9.72.245:4010
## Método: "GET"
## Formato de dados:
Solicitação: QueryString
Resposta: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
nome da interface da interface da província: /getProvince
Request
: Sem parâmetros
Resposta: { "province":["Pequim","Tianjin","Hebei",...]}
nome da interface:/getCity
request:?province="Hebei"
resposta: {"cidade ":["Shijiazhuang" , "Tangshan", "Qinhuangdao",...]}
nome da interface: /getCounty
solicitação: ?city="Shijiazhuang"
resposta: {"county":["Distrito de Chang'an ", "Qiaodong District", "Qiaoxi District",...]}
<!DOCTYPE html> <html> <cabeça> <meta charset="UTF-8"> <meta name="viewport" content="largura=largura do dispositivo, escala inicial=1,0"> <título>Documento</título> </head> <corpo> <script type="módulo"> importar QueryString de './js/QueryString.js'; importar DropDownMemu de './js/DropDownMemu.js'; deixe cityInfo = {}; iniciar(); função inicialização(){ ajax("http://10.9.72.245:4010","getProvince").then(successFunction).catch(failFunction); } //Executar após comunicação ajax bem-sucedida: função sucessoFunction(_data){ deixe dados = JSON.parse(_data); deixe chave = Object.keys(dados)[0]; dados = Object.valores(dados)[0]; if(DropDownMemu.Obj[chave]){ DropDownMemu.Obj[chave].lista = dados; DropDownMemu.Obj[chave].nome = dados[0]; }outro{ deixe memu = novo DropDownMemu(chave); memu.addEventListener("alterar",changeHandler); memu.lista = dados; memu.nome =dados[0]; memu.appendTo("corpo"); cidadeInfo[chave] = dados[0]; } } // Quando o conteúdo de exibição do menu muda, recebe o evento lançado pelo menu e obtém as informações transportadas no evento, como {"province":"Shaanxi"} ou {"city":"Xi'an"} função changeHandler(e){ deixe chave = e.currentTarget.label; cityInfo[chave] = e.data[chave]; deixe interfaceName; if(e.data.province){ interfaceNome = "getCidade"; }else if(e.data.city){ interfaceNome = "getCounty"; }outro{ retornar } ajax("http://10.9.72.245:4010",interfaceName,cityInfo).then(successeFunction).catch(failFunction); } /* comunicação ajax: Lista de parâmetros: url: endereço de serviço em segundo plano interfaceType: tipo de interface, como "getProvince" dados: dados transmitidos, por exemplo: {"province":"Shaanxi"} Tipo de comunicação: solicitação "GET" padrão para enviar dados no formato json: o padrão é falso */ função ajax(url,interfaceType,data,type="get",json=false){ tipo = type.toUpperCase(); deixe o = type==="GET"? nulo: dados; if(dados) dados = json? JSON.stringify(dados): QueryString.stringify(dados); senão dados = ""; retornar nova Promessa(função(resolver,rejeitar){ deixe xhr = new XMLHttpRequest(); xhr.open(type,url + "/" + interfaceType + (type==="GET"? "?"+data : "")); xhr.send(o); xhr.onreadystatechange=função(){ if(xhr.readyState===4 && xhr.status===200){ resolver(xhr.resposta); }else if(xhr.readyState===4){ resolver(xhr.status); } } xhr.onerror= function(){ rejeitar(xhr.resposta); } }) } //Executa a função failFunction(_err){ quando a comunicação ajax falha console.log(_err); } </script> </body> </html>
Componente de importação da classe DropDownMemu de "./Component.js"; exportar classe padrão DropDownMemu estende o componente { _list; // Opções atuais do menu suspenso. _name; //O nome atualmente selecionado para exibição, por exemplo: "Pequim" label; //O rótulo do menu suspenso atual, província cidade condado spanLabel; // Label container spanCaret; // Triângulo ul; // Opção drop-down container bool=false; //Defina o estilo do menu suspenso de acordo com os diferentes estados. estático DROPDOWN = Símbolo(); estático PADRÃO = Símbolo(); // Variáveis globais estáticas são armazenadas neste objeto toda vez que um menu suspenso é criado, e cada menu suspenso criado é gerenciado globalmente. Obj estático = {}; construtor(_label) { super("p"); este.label = _label; //Cria estrutura HTML this.render(); //Defina o estilo this.setStyle(); // O mouse desliza para dentro e para fora e clica, o foco fica fora de foco, o evento de clique 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("clique", e => this.mouseHandler(e)); } mouseHandler(e){ switch(e.type){ caso "mouseenter": if(this.bool) retornar this.elem.style.backgroundColor = "#e6e6e6"; quebrar; caso "mouseleave": if(this.bool) retornar this.elem.style.backgroundColor = "#fff"; quebrar; caso "foco": this.setState(DropDownMemu.DROPDOWN); isto.bool = verdadeiro; quebrar; caso "foco fora": this.setState(DropDownMemu.DEFAULT); isto.bool = falso; caso "clique": if(e.target.constructor !== HTMLLIElement) retornar this._name = e.target.textContent; // Modifica o conteúdo exibido atualmente quando clicado, redefine o estilo e lança eventos para informar o mundo externo sobre o conteúdo atual. this.setContent(); deixe evt = new FocusEvent("focusout"); this.elem.dispatchEvent(evt); } } definir nome(_nome){ este._nome = _nome; this.setContent(); } obter nome(){ retorne isto._nome; } definir lista(_lista){ esta._lista = _lista; this.ul.innerHTML = ""; this.ul.appendChild(this.createLi()); } // Modifica o conteúdo atualmente exibido do menu e lança dados setContent(_name){ este._nome = _nome || este._nome; this.spanLabel.textContent = this._name; deixe evt = new MouseEvent("alterar"); if(!evt.data) evt.data = {} evt.data[this.label] = this._name; this.dispatchEvent(evt); } //Cria uma opção de menu suspenso com base na lista especificada. criarLi(_lista){ esta._lista = _lista || esta._lista; deixe elem = document.createDocumentFragment(); this._list.forEach((item, índice) => { deixe li = document.createElement("li"); li.textContent = item; Object.assign(li.style, { altura da linha:"26px", preenchimento:"0 15px", }) elem.appendChild(li); }) elemento de retorno; } setEstado(tipo){ mudar(tipo){ caso DropDownMemu.DROPDOWN: this.elem.style.backgroundColor = "#e6e6e6"; this.ul.style.display = "bloquear"; quebrar; caso DropDownMemu.DEFAULT: this.elem.style.backgroundColor = "#fff"; this.ul.style.display = "nenhum"; quebrar; } } anexarTo(pai){ super.appendTo(pai); DropDownMemu.Obj[este.label] = isto; } renderizar() { 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); } setEstilo() { Object.assign(this.elem.style, { float: "esquerda", minHeight: "20px", minWidht: "80px", cor: "#333", peso da fonte: "normal", textAlign: "centro", espaço branco: "nowrap", verticalAlign: "meio", cursor: "ponteiro", borda: "1px sólido #ccc", borderRadius: "4px", cor de fundo: "#fff", preenchimento: "6px 12px", tamanho da fonte: "14px", userSelect: "nenhum", margemDireita: "100px", posição:"relativo", }); Object.assign(this.spanLabel.style, { float: "esquerda", preenchimento: "0 5px" }) Object.assign(this.spanCaret.style, { display: "bloco embutido", verticalAlign: "meio", borderTop: "4px tracejado", borderRight: "4px sólido transparente", borderLeft: "4px sólido transparente", }) Object.assign(this.ul.style, { listStyle: "nenhum", posição: "absoluta", topo: "100%", esquerda: "0", zIndex: "1000", minWidth: "100px", preenchimento: "5px 0px", margem: "2px 0 0", tamanho da fonte: "14px", textAlign: "esquerda", cor de fundo: "#fff", borda: "1px sólido rgba (0, 0, 0, 0,15)", borderRadius: "4px", boxShadow: "0 6px 12px rgba(0, 0, 0, 0,175)", exibição: "nenhum", }) } }
exportar classe padrão Componente estende EventTarget{ elemento; construtor(_type){ super(); this.elem = this.createElem(_type); } createElem(_type){ deixe elem = document.createElement(_type); elemento de retorno; } anexarTo(pai){ if(typeof parent==="string") parent = document.querySelector(parent); parent.appendChild(este.elem); } }
let http = require("http"); deixe querystring = require("querystring"); deixe os dados, solicitação, res; // Ler todos os dados da cidade e analisá-los em objetos e lê-los de forma síncrona. deixe fs = exigir("fs"); deixe allCityInfo = JSON.parse(fs.readFileSync('./city.json')); deixe servidor = http.createServer(listenerHandler); server.listen(4010,"10.9.72.245",listenerDoneHandler); função listenerHandler(_req,_res){ req = _req; res = _res; res.writeHead(200,{ "content-type":"text/html;charset=utf-8", "Access-Control-Allow-Origin":"*", "Access-Control-Allow-Headers":"*", }); dados=""; req.on("dados",function(_dados){ dados=_dados; }) req.on("end",receiveHandler); } função receberHandler(){ //console.log(allCityInfo); // Analisar o tipo de interface de acordo com a URL do cabeçalho da solicitação let type = req.url.trim().split("?")[0].replace(///g,""); console.log(tipo); // Analisar os parâmetros recebidos de acordo com a URL do cabeçalho da solicitação if(req.method.toUpperCase()==="GET"){ if(req.url.includes("favicon.ico")) return res.end(); senão dados = req.url.includes("?") ? req.url.split("?")[1] : ""; } tentar{ dados = JSON.parse(dados); }pegar{ dados = querystring.parse(dados); } console.log(dados); //Encontre dados com base no tipo de interface. deixe lista = {}; mudar(tipo){ caso "getProvince": lista.province = Object.keys(allCityInfo); quebrar; caso "getCidade": list.city = Object.keys(allCityInfo[data.province]); quebrar; caso "getCounty": lista.condado = allCityInfo[data.province][data.city]; quebrar; } console.log(lista); res.write(JSON.stringify(lista)); res.end() } função ouvinteDoneHandler(){ console.log("Serviço iniciado com sucesso"); }
{
"Pequim": {
"Pequim": ["Distrito de Dongcheng", "Distrito de Xicheng", "Distrito de Chongwen", "Distrito de Xuanwu", "Distrito de Chaoyang", "Distrito de Fengtai", "Distrito de Shijingshan", "Distrito de Haidian", "Distrito de Mentougou", "Distrito de Fangshan", "Distrito de Tongzhou", "Distrito de Shunyi", "Distrito de Changping", "Distrito de Daxing", "Distrito de Pinggu", "Distrito de Huairou", "Condado de Miyun", "Condado de Yanqing", "Outros"]
} ,
"Tianjin": {
"Tianjin": ["Distrito de Heping", "Distrito de Hedong", "Distrito de Hexi", "Distrito de Nankai", "Distrito de Hebei", "Distrito de Hongjiao", "Novo Distrito de Binhai", "Distrito de Dongli", "Distrito de Xiqing" Distrito", "Distrito de Jinnan", "Distrito de Beichen", "Distrito de Ninghe", "Distrito de Wuqing", "Condado de Jinghai", "Distrito de Baodi", "Jixian", "Distrito de Tanggu", "Distrito de Hangu", "Distrito de Dagang ", "Baodi District", "Others"]
},
}
O acima é uma explicação detalhada do menu de ligação de três níveis usando JS (com explicação de ideias). Para obter mais informações, preste atenção a outros artigos relacionados no PHP Site chinês!