实现效果
实现思路
- 开始设置默认值,获取最初的菜单状态
- 每次点击向后端通信,获取点击后的相应省/市/区的数据
- 获取到相应的数据后,再次重新渲染页面
项目接口文件
URL: http://10.9.72.246:4010
Method: POST
DataType:
请求消息: QueryString
相应消息: JSON
接口名称
- http http://10.9.72.246/province
- http http://10.9.72.246/city
- http http://10.9.72.246/country
获取省级数据
接口名:province
请求: 无参数或者省级名称
响应:{
“北京”:{
“北京”: [“东城区”, “西城区”, “崇文区”, “宣武区”, “朝阳区”, “丰台区”, “石景山区”, “海淀区”, “门头沟区”, “房山区”, "通州区"能, “顺义区”, “昌平区”, “大兴区”, “平谷区”, “怀柔区”, “密云县”, “延庆县”, “其他”]
},
}
…
}
市级数据
接口名:city
请求: province = “河北” 省级名称
响应:{
“石家庄”,
“秦皇岛”,
“保定”,
…
}
区级数据
接口名:country
请求: {
province: “河北”,
city: “石家庄”
}
响应: [
“长安区”, “桥东区”, “桥西区”, “新华区”, “井陉矿区”, “裕华区”, “井陉县”, “正定县”, “栾城县”, “行唐县”, “灵寿县”, “高邑县”, “深泽县”, “赞皇县”, “无极县”, “平山县”, “元氏县”, “赵县”, “辛集市”, “藁城市”, “晋州市”, “新乐市”, “鹿泉市”, “其他”
]
服务端代码
var data = require("./data.js");
var http = require("http");
var querystring = require("querystring");
var req, res;
var server = http.createServer(function (_req, _res) {
var reqData = "";
req = _req;
res = _res;
res.writeHead(200, {
"content-type": "text/html;charset=utf-8",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "*",
});
req.on("data", function (_data) {
reqData += _data;
});
req.on("end", function () {
var type = req.url.trim().split("?")[0].replace(/\//g, "");
if (req.method.toLowerCase() === "get") {
if (req.url.includes("favicon.ico")) return res.end();
reqData = req.url.includes("?") ? req.url.split("?")[1] : "";
}
try {
reqDate = JSON.parse(data);
} catch (e) {
reqData = data ? querystring.parse(reqData) : {};
}
var o = {};
switch (type) {
case "province":
if (JSON.stringify(reqData) === "{}") {
for (var prop in data) {
o[prop] = prop;
}
} else {
o[reqData.province] = data[reqData.province];
}
break;
case "city":
for (var province in data) {
if (province === reqData.province) {
o = data[province];
}
}
break;
case "country":
for (var province in data) {
for (var city in data[province]) {
if (city === reqData.city) {
o = data[province][city];
}
}
}
break;
}
res.end(JSON.stringify(o));
});
});
server.listen(4010, "10.9.72.246", function () {
console.log("服务已经开启!");
});
生成菜单代码
export default class ThreeLevel {
data;
elem;
province;
city;
courty;
select;
p;
c;
pre = 0;
constructor(_data) {
this.data = _data;
this.elem = document.createElement("div");
this.province = document.querySelector(".province");
this.city = document.querySelector(".city");
this.courty = document.querySelector(".country");
this.createOptions(_data, this.province);
}
createOptions(_data, _select) {
var data = _data;
var df = document.createDocumentFragment();
if (_select.options.length) {
_select.removeEventListener("change", this.changeHandler);
_select.removeEventListener("mousedown", this.mouseHandler);
_select.removeEventListener("mouseout", this.mouseHandler);
_select.options.length = 0;
}
if ({}.toString.call(data).includes("Object")) {
var bool = false;
for (var prop in data) {
var option = document.createElement("option");
if (!bool) {
option.setAttribute("selected", "selected");
bool = true;
}
option.textContent = prop;
df.appendChild(option);
}
_select.addEventListener("change", (e) => this.changeHandler(e));
_select.addEventListener("mousedown", (e) => this.mouseHandler(e));
_select.addEventListener("mouseout", (e) => this.mouseHandler(e));
} else {
for (var i = 0; i < data.length; i++) {
var option = document.createElement("option");
option.textContent = data[i];
df.appendChild(option);
}
}
_select.appendChild(df);
}
changeHandler(e) {
// console.log("start");
var select = e.currentTarget;
var index = select.selectedIndex;
console.log(index);
var txt = select.options[index].value;
if (select.className === "province") {
var data = this.data[txt];
this.p = txt;
this.c = "";
this.createOptions(data, this.city);
} else if (select.className === "city") {
this.c = txt;
var data = this.data[this.p][this.c];
this.createOptions(data, this.courty);
}
}
mouseHandler(e) {
var select = e.currentTarget;
// console.log(select);
if (e.type === "mousedown") {
console.log("second");
this.pre = select.selectedIndex;
// console.log(this.pre);
select.selectedIndex = -1;
} else if (e.type === "mouseout") {
var index = select.selectedIndex;
console.log(this.pre);
if (index == -1) {
select.selectedIndex = this.pre;
}
}
}
}
前端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script type=module>
import ThreeLevel from "./js/ThreeLevel.js";
var threeLevel = new ThreeLevel();
threeLevel.appendTo("body");
</script>
</body>
</html>