Идея: каждое раскрывающееся меню как компонент может получать набор данных и генерировать различные параметры меню на основе различного содержимого данных. Корреляция между тремя уровнями достигается посредством генерации событий. Данные получены из фона.
При нажатии на меню провинции для выбора Шэньси компонент меню выдает текущую провинцию посредством генерации событий. Зная провинцию, вы можете получить данные о городе в провинции из фона. И так далее.
Эффект реализации:
## URL: http://10.9.72.245:4010
## Метод: «GET»
## Формат данных:
Запрос: QueryString
Ответ: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
: /getProvince
Request
: Нет параметров
Ответ: { "province":["Пекин","Тяньцзинь","Хэбэй",...]}
имя интерфейса:/getCity
request:?province="Hebei"
ответ: {"city ":["Шицзячжуан" , "Таншань", "Циньхуандао",...]}
имя интерфейса: /getCounty
запрос: ?city="Шицзячжуан"
ответ: {"county":["Район Чанъань ", "Район Цяодун", "Район Цяоси",...]}
<!DOCTYPE html> <html> <голова> <мета-кодировка="UTF-8"> <meta name="viewport" content="width=device-width, Initial-scale=1.0"> <title>Документ</title> </голова> <тело> <тип сценария="модуль"> импортировать QueryString из './js/QueryString.js'; импортировать DropDownMemu из «./js/DropDownMemu.js»; пусть cityInfo = {}; инициализация(); функция инициализации(){ ajax("http://10.9.72.245:4010","getProvince").then(successFunction).catch(failFunction); } //Выполнить после успешной связи ajax: функция succeseFunction(_data){ пусть данные = JSON.parse(_data); пусть ключ = Object.keys(данные)[0]; данные = Object.values(данные)[0]; если (DropDownMemu.Obj [ключ]) { DropDownMemu.Obj[ключ].list = данные; DropDownMemu.Obj[ключ].имя = данные[0]; }еще{ пусть memu = новый DropDownMemu (ключ); memu.addEventListener("изменить",changeHandler); memu.list = данные; memu.name = данные [0]; memu.appendTo("тело"); cityInfo[ключ] = данные[0]; } } // Когда содержимое отображения меню меняется, получаем событие, генерируемое меню, и получаем информацию, содержащуюся в событии, например {"провинция":"Шэньси"} или {"город":"Сиань"} функция ChangeHandler(e){ пусть ключ = e.currentTarget.label; cityInfo[ключ] = e.data[ключ]; пусть имя интерфейса; если (e.data.province) { имя интерфейса = "getCity"; }иначе если(e.data.city){ имя интерфейса = "getCounty"; }еще{ возвращаться } ajax("http://10.9.72.245:4010",interfaceName,cityInfo).then(successeFunction).catch(failFunction); } /* аякс-связь: Список параметров: url: адрес фоновой службы. InterfaceType: тип интерфейса, например «getProvince». данные: передаваемые данные, например: {"провинция":"Шэньси"} Тип связи: запрос «GET» по умолчанию, отправлять ли данные в формате json: значение по умолчанию — false. */ функция ajax(url,interfaceType,data,type="get",json=false){ тип = type.toUpperCase(); пусть о = тип ==="GET" ноль: данные; если (данные) данные = json? JSON.stringify (данные): QueryString.stringify (данные); еще данные = ""; вернуть новое обещание (функция (разрешить, отклонить) { пусть xhr = новый XMLHttpRequest(); xhr.open(type,url + "/" +interfaceType + (type==="GET"? "?"+data: "")); xhr.send(о); xhr.onreadystatechange = функция(){ if(xhr.readyState===4 && xhr.status===200){ разрешить (xhr.response); }иначе если(xhr.readyState===4){ разрешить (xhr.status); } } xhr.onerror= функция(){ отклонить (xhr.response); } }) } //Выполнение функцииfailFunction(_err){ при сбое связи ajax console.log(_err); } </скрипт> </тело> </html>
импорт компонента из "./Component.js"; класс экспорта по умолчанию DropDownMemu расширяет компонент { _list; // Текущие параметры раскрывающегося меню. _name; //Выбранное в данный момент имя для отображения, например: «Пекин» label; //Метка текущего раскрывающегося меню, провинция, город, округ. spanLabel; // Контейнер меток spanCaret; // Triangle ul; // Контейнер раскрывающихся опций bool=false; // Управляйте событиями мыши, состоянием фокуса или выбором, не запускайте эффект выдвижения и выдвижения мыши. //Устанавливаем стиль раскрывающегося меню в соответствии с разными состояниями. статический РАСПАДЕНИЕ = Символ(); статический ПО УМОЛЧАНИЮ = Символ(); // Статические глобальные переменные сохраняются в этом объекте каждый раз, когда создается раскрывающееся меню, и каждое созданное раскрывающееся меню управляется глобально. статический объект = {}; конструктор(_label) { супер("р"); this.label = _label; //Создаем HTML-структуру this.render(); //Установим стиль this.setStyle(); // Мышь скользит и щелкает, фокус не в фокусе, событие щелчка 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)); } mouseHandler (е) { переключатель (e.type) { случай «mouseenter»: если(this.bool) вернуть this.elem.style.backgroundColor = "#e6e6e6"; перерыв; случай «mouseleave»: если(this.bool) вернуть this.elem.style.backgroundColor = "#fff"; перерыв; случай «фокусин»: this.setState(DropDownMemu.DROPDOWN); this.bool = правда; перерыв; случай «фокус»: this.setState(DropDownMemu.DEFAULT); this.bool = ложь; случай «щелчок»: if(e.target.constructor !== HTMLLIElement) return this._name = e.target.textContent; // Измените отображаемый в данный момент контент при нажатии, сбросьте стиль и создайте события, чтобы сообщить внешнему миру о текущем контенте. это.setContent(); пусть evt = новый FocusEvent("focusout"); this.elem.dispatchEvent(evt); } } установить имя (_name) { это._имя = _имя; это.setContent(); } получить имя(){ верните это._имя; } установить список (_list) { this._list = _list; this.ul.innerHTML = ""; this.ul.appendChild(this.createLi()); } // Изменяем отображаемое в данный момент содержимое меню и выдаем данные setContent(_name){ это._имя = _имя || это._имя; this.spanLabel.textContent = this._name; пусть evt = new MouseEvent("изменить"); if(!evt.data) evt.data = {} evt.data[this.label] = this._name; this.dispatchEvent(evt); } //Создаем пункт раскрывающегося меню на основе указанного списка. createLi(_list){ этот._список = _список || этот._список; пусть elem = document.createDocumentFragment(); this._list.forEach((элемент, индекс) => { let li = document.createElement("li"); li.textContent = элемент; Object.assign(li.style, { lineHeight:"26px", отступ: "0 15px", }) элем.appendChild(ли); }) вернуть элемент; } setState (тип) { переключатель(тип){ случай DropDownMemu.DROPDOWN: this.elem.style.backgroundColor = "#e6e6e6"; this.ul.style.display = "блокировать"; перерыв; случай DropDownMemu.DEFAULT: this.elem.style.backgroundColor = "#fff"; this.ul.style.display = "нет"; перерыв; } } AppendTo (родитель) { super.appendTo(родительский); DropDownMemu.Obj[this.label] = это; } оказывать() { 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() { Object.assign(this.elem.style, { плавать: «влево», minHeight: "20 пикселей", minWidht: "80 пикселей", цвет: "#333", FontWeight: «нормальный», textAlign: "центр", whiteSpace: "nowrap", вертикальноеВыравнивание: «средний», курсор: «указатель», граница: "1 пиксель сплошной #ccc", borderRadius: "4px", Цвет фона: "#fff", отступ: "6px 12px", Размер шрифта: "14 пикселей", userSelect: «нет», MarginRight: "100 пикселей", позиция:"родственник", }); Object.assign(this.spanLabel.style, { плавать: «влево», отступ: "0 5px" }) Object.assign(this.spanCaret.style, { дисплей: «встроенный блок», вертикальноеВыравнивание: «средний», borderTop: "4 пикселя пунктирный", borderRight: "4 пикселя сплошной прозрачный", borderLeft: "4 пикселя сплошной прозрачный", }) Object.assign(this.ul.style, { listStyle: «нет», позиция: «абсолютная», вверху: «100%», слева: «0», zИндекс: "1000", minWidth: "100 пикселей", отступ: "5px 0px", поле: "2px 0 0", Размер шрифта: "14 пикселей", textAlign: «слева», Цвет фона: "#fff", border: "1px сплошной rgba(0, 0, 0, 0,15)", borderRadius: "4px", boxShadow: "0 6px 12px rgba(0, 0, 0, 0,175)", отображение: «нет», }) } }
экспортировать класс по умолчанию. Компонент расширяет EventTarget{ элем; конструктор(_type){ супер(); this.elem = this.createElem(_type); } createElem(_type){ пусть elem = document.createElement(_type); вернуть элемент; } AppendTo (родитель) { if(typeof родительский==="строка") родительский = document.querySelector(родительский); родитель.appendChild(this.elem); } }
let http = require("http"); let querystring = require("querystring"); пусть данные, требуется, рез; // Считываем все данные города, разбираем их на объекты и читаем синхронно. let fs = require("fs"); let allCityInfo = JSON.parse(fs.readFileSync('./city.json')); пусть сервер = http.createServer(listenerHandler); server.listen(4010,"10.9.72.245",listenerDoneHandler); функция ListenerHandler(_req,_res){ требование = _req; рез = _res; res.writeHead(200,{ "content-type":"text/html;charset=utf-8", "Контроль доступа-Разрешить-Origin":"*", "Заголовки-Control-Allow-Headers":"*", }); данные=""; req.on("данные",функция(_data){ данные = _данные; }) req.on("конец",receiveHandler); } функция полученияHandler(){ // console.log(allCityInfo); // Анализируем тип интерфейса по URL-адресу заголовка запроса let type = req.url.trim().split("?")[0].replace(///g,""); console.log(тип); // Анализируем входящие параметры по URL-адресу заголовка запроса if(req.method.toUpperCase()==="GET"){ if(req.url.includes("favicon.ico")) return res.end(); else data = req.url.includes("?") ? req.url.split("?")[1] : ""; } пытаться{ данные = JSON.parse(данные); }ловить{ данные = querystring.parse(данные); } console.log(данные); //Находим данные по типу интерфейса. пусть список = {}; переключатель(тип){ случай «getProvince»: list.province = Object.keys(allCityInfo); перерыв; случай «getCity»: list.city = Object.keys(allCityInfo[data.province]); перерыв; случай «getCounty»: list.county = allCityInfo[data.province][data.city]; перерыв; } console.log(список); res.write(JSON.stringify(список)); рез.конец() } функция прослушивательDoneHandler(){ console.log("Служба запущена успешно"); }
{
"Пекин": {
«Пекин»: [«Район Дунчэн», «Район Сичэн», «Район Чунвэнь», «Район Сюаньу», «Район Чаоян», «Район Фэнтай», «Район Шицзиншань», «Район Хайдянь», «Район Мэнтогоу», «Район Фаншань», «Район Тунчжоу», «Район Шуньи», «Район Чанпин», «Район Дасин», «Район Пингу», «Район Хуайжоу», «Уезд Миюнь», «Уезд Яньцин», «Другие»]
} ,
"Тяньцзинь": {
«Тяньцзинь»: [«Район Хэпин», «Район Хэдун», «Район Хэси», «Район Нанкай», «Район Хэбэй», «Район Хунцзяо», «Новый район Биньхай», «Район Дунли», «Район Сицин» Район», «Район Цзиньнань», «Район Бэйчен», «Район Нинхэ», «Район Уцин», «Округ Цзинхай», «Район Баоди», «Цзисян», «Район Тангу», «Район Хангу», «Район Даган» ", "Район Баоди", "Другие"]
},
}
Выше приведено подробное объяснение трехуровневого меню связи с использованием JS (с объяснением идей). Для получения дополнительной информации, пожалуйста, обратите внимание на другие статьи по теме PHP. Китайский сайт!