29_用js实现一个省市级联效果

一、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
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,701评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,649评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,037评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,994评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,018评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,796评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,481评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,370评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,868评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,014评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,153评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,832评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,494评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,039评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,156评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,437评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,131评论 2 356

推荐阅读更多精彩内容