二十九、用js实现一个省市级联效果

209 阅读2分钟

一、JavaScript 省市级联效果

1、代码


<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<meta http-equiv="X-UA-Compatible" content="ie=edge">

<title>用js实现一个省市级联效果</title>

</head>

<body>

<select id="prov">

<option value="none">请选择省</option>

</select>

<select id="city" style="display:none"></select>

</body>

<script>

var provs={

"江西省":["南昌市", "景德镇", "九江", "鹰潭", "萍乡", "新馀", "赣州", "吉安", "宜春", "抚州", "上饶"],

"福建省":["福州", "厦门", "莆田", "三明", "泉州", "漳州", "南平", "龙岩", "宁德"],

"河北省":["石家庄", "邯郸", "邢台", "保定", "张家口", "承德", "廊坊", "唐山", "秦皇岛", "沧州", "衡水"]

};

function loadProv() {

var prov = document.getElementById("prov");

for (var key in provs) {

var provName = key;

var optProv = document.createElement("option");

optProv.value = provName;

optProv.innerText = provName;

prov.appendChild(optProv);

}

}

function provChange() {

var prov = document.getElementById("prov");

var city = document.getElementById("city");

var provName = prov.value;

if (provName == "none") {

city.style.display = "none";

return;

}

else {

city.style.display = "";

}

var citys = provs[provName];

for (var index = city.childNodes.length - 1; index >= 0; index--) {

var child = city.childNodes[index];

city.removeChild(child);

}

for (var index = 0; index < citys.length; index++) {

var optCity = document.createElement("option");

optCity.value = citys[index];

optCity.innerText = citys[index];

city.appendChild(optCity);

}

}

window.onload=function(){

loadProv();

var prov = document.getElementById("prov");

prov.onchange=function(){provChange()}

}

</script>

</html>

2、代码注释

(1)var provs={},存储省市的json结构数据。

(2)function loadProv() {},此函数实现了初始化页面加载数据的功能。

(3)var prov = document.getElementById("prov"),获取存放省份的select下拉菜单。

(4)for (var key in provs),遍历json结构数据。

(5)var provName = key,获取省份的名称。

(6)var optProv = document.createElement("option"),创建一个option元素对象。

(7)optProv.value = provName,设置option元素的value属性值。

(8)optProv.innerText = provName,设置option显示的文本内容。

(9)prov.appendChild(optProv),将option元素添加到select下拉菜单。

(10)function provChange() {},作为onchange事件处理函数。

(11)var prov = document.getElementById("prov"),获取省份下拉菜单。

(12)var city = document.getElementById("city"),获取城市下拉菜单。

(13)var provName = prov.value,获取当前选中的省份的value值。

(14)if (provName == "none") {

city.style.display = "none";

return;

},如果值等于none,说明选中的是第一项,那么城市下拉菜单还是具有隐藏状态,并跳出函数。

(15)else {

city.style.display = "";

},否则的话显示出城市下拉菜单,默认状态它是隐藏的。

(16)var citys = provs[provName],获取城市,citys是个数组。

(17)for (var index = city.childNodes.length - 1; index >= 0; index--) {

var child = city.childNodes[index];

city.removeChild(child);

},遍历城市下拉菜单下的option元素,然后删除这些元素。

之所以清空就是为了防止当再次加载的时候出现累加情况。

(18)for (var index = 0; index < citys.length; index++) {},遍历数组中的元素,也就是城市。

(19)var optCity = document.createElement("option"),创建option元素。

(20)optCity.value = citys[index],设置option元素的value值。

(21)optCity.innerText = citys[index],设置option元素的文本内容。

(22)city.appendChild(optCity),将option元素添加select下拉菜单。

二、js递归算法实现无限级树形菜单

效果图

image

数据类型一

1、mysql表结构形式数据


var data = [

{ id: 1, name: '广东', pid: 0 },

{ id: 2, name: '广州', pid: 1 },

{ id: 3, name: '天河', pid: 2 },

{ id: 4, name: '白云', pid: 2 },

{ id: 5, name: '广西', pid: 0 },

{ id: 6, name: '玉林', pid: 5 },

{ id: 7, name: '北流', pid: 6 },

{ id: 8, name: '深圳', pid: 1 },

{ id: 9, name: '东莞', pid: 1 },

{ id: 10, name: '松山湖', pid: 9 },

]

2、js实现部分


var menu = '';

menuFn(0, data)

$("body").append(menu)

function menuFn(id, data) {

if (data.length > 0) {

for (var i = 0; i < data.length; i++) { //获取省一级

if (data[i].pid == id) {

// console.log(data[i])

menu += "<ul>"

menu += "<li>" + data[i].name

// menu += "<li>"+"id::" + data[i].id + ",name:"+ data[i].name + ",pid:"+ data[i].pid

menuFn(data[i].id, data) //递归

menu += "</li>"

menu += "</ul>"

}

}

return menu;

}

}

数据类型二

1、json结构形式数据


var data = [

{

id: 1, name: "广东", pid: 0,

children: [

{

id: 2, name: "广州", pid: 1,

children: [

{ id: 3, name: "天河", pid: 2 },

{ id: 4, name: "白云", pid: 2 },

],

},

{ id: 8, name: "深圳", pid: 1 },

{

id: 9, name: "东莞", pid: 1,

children: [

{ id: 10, name: "松山湖", pid: 9 },

]

},

]

},

{

id: 5, name: "广西", pid: 0,

children: [

{

id: 6, name: "玉林", pid: 5,

children: [

{ id: 7, name: "北流", pid: 6 },

]

},

]

},

];

2、js实现


var menu = '';

menuFn(0, data)

$("body").append(menu)

function menuFn(id, data) {

if (data.length > 0) {

for (var i = 0; i < data.length; i++) { //获取省一级

if (data[i].pid == id) {

// console.log(data[i])

menu += "<ul>"

menu += "<li>" + data[i].name

// menu += "<li>"+"id::" + data[i].id + ",name:"+ data[i].name + ",pid:"+ data[i].pid

if (data[i].children) {

menuFn(data[i].id, data[i].children) //递归

}

menu += "</li>"

menu += "</ul>"

}

}

return menu;

}

}

两者区别

数据表形式数据


menuFn(data[i].id, data) //递归

json形式数据


if (data[i].children) {

menuFn(data[i].id, data[i].children) //递归

}

多级折叠菜单

效果图

image

说明

this指向


function fn() {

// console.log(this) //span em

}

$("#app").delegate("span", "click", fn)

$("#app").delegate("em", "click", fn)

两者区别


$(this).parent().children("ul")[0]

$($(this).parent().children("ul")[0])

image

代码


<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<meta http-equiv="X-UA-Compatible" content="ie=edge">

<title>Document</title>

</head>

<style>

ul,

li {

list-style: none;

}

li {

position: relative;

line-height: 30px;

padding-left: 20px

}

em {

position: absolute;

top: 7px;

left: 0;

width: 16px;

height: 16px;

background: url("jian.png") no-repeat;

cursor: pointer;

background-size: 16px 16px;

}

em.open{

background: url("jia.png") no-repeat;

background-size: 16px 16px;

}

</style>

<body>

<div id="app"></div>

<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>

<script>

$(function () {

var data = [

{

id: 1, name: "广东", pid: 0,

children: [

{

id: 2, name: "广州", pid: 1,

children: [

{ id: 3, name: "天河", pid: 2 },

{ id: 4, name: "白云", pid: 2 },

],

},

{ id: 8, name: "深圳", pid: 1 },

{

id: 9, name: "东莞", pid: 1,

children: [

{ id: 10, name: "松山湖", pid: 9 },

]

},

]

},

{

id: 5, name: "广西", pid: 0,

children: [

{

id: 6, name: "玉林", pid: 5,

children: [

{ id: 7, name: "北流", pid: 6 },

]

},

]

},

];

var menu = '';

menuFn(0, data)

$("#app").append(menu)

function menuFn(id, data) {

if (data.length > 0) {

menu += "<ul>"

for (var i = 0; i < data.length; i++) { //获取省一级

if (data[i].pid == id) {

menu += "<li>"

if(data[i].children){

menu += '<em></em><span>' + data[i].name + "</span>"

menuFn(data[i].id, data[i].children) //递归

}else{

menu += '<span>' + data[i].name + "</span>"

}

menu += "</li>"

}

}

menu += "</ul>"

return menu;

}

}

function fn() {

var ull = $($(this).parent().children("ul")[0]);

if (ull.length > 0) {

ull.toggle();

$(this).toggleClass("open")

}

}

$("#app").delegate("span", "click", fn)

$("#app").delegate("em", "click", fn)

})

</script>

</body>

</html>

自定义修改树状数据


function formatTree(data) {

const treeData = []

data.forEach((list) => {

const newData = {}

newData.key = list.id

newData.value = list.id

newData.title = list.name

newData.children = list.children ? formatTree(list.children) : []

treeData.push(newData)

})

return treeData

}