原生js写简单三级联动以及复杂三级联动
1. 简单三级联动
效果图:
思想:当选择省时,创建对应的市子对象,并将其加入父元素中。当选择某一个市时,创建对应的区子对象,并将其加入父元素中。当选择其他省/市时,对应的市、区/区的选项都变为请选择。要注意:在每次重新选择时,需要将其余
select
标签的options
元素的长度为1,即做一次清空。知识点:① 在创建
<select></select>
标签的子元素<options></options>
时,可采用new Option(innerHTML,value)
的方式。每次可通过option的value值来对应到所选数据在json串中的位置。从而将其余<select></select>
的子元素内容变为所选择的对应的children内容。
② 想要删除<select></select>
的子元素时,可采用让对象.options.length=1
的方式。eg:若想要让sheng对象的子元素option
的长度为1,则:sheng.options.length=1;
注意: 不能用sheng.children.length=1
,children.length
不可被修改
③ 监听select
标签的选中元素变化事件为:对象名.onchange=function(){]
完整代码
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div>
省:<select class="sheng">
<option>
-请选择-
</option>
</select>
市:<select class="shi">
<option>
-请选择-
</option>
</select>
区:<select class="qu">
<option>
-请选择-
</option>
</select>
</div>
<script> var city = [ { "id": 10001, "name": "陕西省", "child": [ { "id": 100011, "name": "西安市", "child": [ { "id": 100011, "name": "高新区" }, { "id": 100011, "name": "未央区" } ] }, { "id": 100012, "name": "宝鸡市", "child": [ { "id": 100011, "name": "高新区" }, { "id": 100011, "name": "成仓区" } ] } ] }, { "id": 10002, "name": "甘肃省", "child": [ { "id": 100021, "name": "兰州市", "child": [ { "id": 100021, "name": "兰州区1" }, { "id": 100021, "name": "兰州区2" } ] }, { "id": 100022, "name": "酒泉市", "child": [ { "id": 100021, "name": "酒泉区1" }, { "id": 100021, "name": "酒泉区2" } ] } ] } ] var sheng = document.getElementsByClassName("sheng")[0]; var shi = document.getElementsByClassName("shi")[0]; var qu = document.getElementsByClassName("qu")[0]; var nowShengIndex = 0; for(var i=0;i<city.length;i++){ var optEle = new Option(city[i].name,i); console.log(optEle.innerHTML); sheng.appendChild(optEle) } sheng.onchange=function(){ shi.options.length = 1; qu.options.length = 1; //this.value可取到当前所选值对应的索引 for(var i=0;i<city[this.value].child.length;i++){ var optEle = new Option(city[this.value].child[i].name,i); shi.appendChild(optEle) } nowShengIndex = this.value; }; shi.onchange=function () { qu.options.length = 1; console.log(qu); for(var i=0;i<city[nowShengIndex].child[this.value].child.length;i++){ var optEle = new Option(city[nowShengIndex].child[this.value].child[i].name,i); qu.appendChild(optEle) } } </script>
</body>
</html>
2. 复杂的三级联动
效果图:
步骤:
① 在文本框输入触发onkeyup
事件,在该事件中对输入的字符与json串中的省份的名字进行匹配,将匹配的所有身份的名称显示到搜索结果的内容框中,若没有任何匹配,则不显示搜索结果框。在进入该事件前,要先将搜索结果内容框清空,否则几次的搜索结果都会显示出来。(默认搜索结果框是隐藏的,只有当有匹配的名称时才会出现)
② 点击搜索结果内容框内任何一个元素,内容框消失,刚才点击的内容显示到搜索框中。并且点击的内容的index赋给搜索框。
③ 点击搜索按钮,搜索框的index值赋给搜索按钮。通过该index搜索到该省份的child
,将其push
到userStor
数组中,再将该数组的最后一个索引内的所有name
都显示到content
中,并将每一个name
所在索引赋给该name
对象(userStor
数组的最后一个索引对应的name
是相关市)
④ ③中的userStor
是为了将点击市、区、镇…等按钮的点击事件封装起来操作。
⑤ 点击content
内的每一个子元素,将该子元素的内容和索引赋值给topContent
中的创建的一个新的子元素内容和索引,为创建的新的子元素创建一个x
子元素,并给其赋值其在userStor
中的索引(取当前userStor
的长度-1即可)(以便后来的操作),再将当前点击内容的child
push
进userStor
,并且content
中显示点击的元素对应的所有child的名称(即userStor
的最后索引对应的所有name
)。
⑥ 同理,当点击区
、镇
等也是如⑤的操作
⑦ 当点击topContent
中的某个子元素的x
时,将该子元素以及其兄弟元素对应的name
展示到content
中,并且topContent
截去从该元素至结尾的所有元素(可通过x
对应的index
截取userStor
)。知识点:① 可在创建元素时给其添加事件。
完整代码
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<style> .all { width: 700px; height: 400px; margin: auto; border: 1px solid silver; text-align: center; } .searchTop { padding: 20px 0; border-bottom: 1px solid black; position: relative; } .inputContent { width: 200px; height: 20px; } .search { border-radius: 15px; text-align: center; width: 60px; border: none; border: 1px solid silver; } .content { width: 95%; margin: auto; border: 1px solid black; height: 260px; text-align: left; padding: 10px; } .searchResult { display: none; width: 200px; height: 100px; border: 1px solid silver; position: absolute; top:70%; left: 31%; background: white;; text-align: left; padding: 0; margin: 0; } ul, li { list-style: none; } .spanEle { display: inline-block; background: #ddd; height: 20px; line-height: 20px; border-radius: 15px; text-align: center; margin: 0 10px; font-size: 12px; padding: 0 10px; } .topContent { text-align: left; height: 29px; width: 95%; border-bottom: 1px solid black; margin: auto; display: flex; justify-content: center; align-items: center; } </style>
<body>
<div class="all">
<div class="searchTop">
<input class="inputContent"/>
<button class="search">搜索</button>
<ul class="searchResult"></ul>
</div>
<div>
<div class="topContent"></div>
<div class="content"></div>
</div>
</div>
<script> var city = [ { "id": 10001, "name": "陕西省", "child": [ { "id": 100011, "name": "西安市", "child": [ { "id": 100011, "name": "高新区", "child": [ { "name": "高新街道1", "child": [ { "name": "高新街道1,38号" }, { "name": "高新街道4,38号" } ] } ] }, { "id": 100011, "name": "未央区" } ] }, { "id": 100012, "name": "宝鸡市", "child": [ { "id": 100011, "name": "高新区", "child":[ { "name":"宝鸡市高新区街道1", "child":[ { "name":"宝鸡市高新区街道1 55号" }, { "name":"宝鸡市高新区街道4 55号" } ] }, { "name":"宝鸡市高新区街道1" } ] }, { "id": 100011, "name": "成仓区", "child":[ { "name":"宝鸡市成仓区街道1", "child":[ { "name":"宝鸡市成仓区街道1 55号" }, { "name":"宝鸡市成仓区街道4 55号" } ] }, { "name":"宝鸡市成仓区街道1" } ] } ] } ] }, { "id": 10002, "name": "甘肃省", "child": [ { "id": 100021, "name": "兰州市", "child": [ { "id": 100021, "name": "兰州区1", "child": [ { "name": "兰州区1街道1", "child": [ { "name": "兰州区1街道1,38号" }, { "name": "兰州区1街道4,38号" } ] } ] }, { "id": 100021, "name": "兰州区2", "child": [ { "name": "兰州区2街道1", "child": [ { "name": "兰州区2街道1,38号" }, { "name": "兰州区2街道4,38号" } ] } ] } ] }, { "id": 100022, "name": "酒泉市", "child": [ { "id": 100021, "name": "酒泉区1" }, { "id": 100021, "name": "酒泉区2" } ] } ] } ] var inputContent = document.getElementsByClassName("inputContent")[0]; var searchResult = document.getElementsByClassName("searchResult")[0]; var search = document.getElementsByClassName("search")[0]; var content = document.getElementsByClassName("content")[0]; var topContent = document.getElementsByClassName("topContent")[0]; var userStor = []; inputContent.onkeyup = function () { //可通过父元素.innerHTML=""来清除父元素内的所有子元素 searchResult.innerHTML = ""; var str = this.value; for (var i = 0; i < city.length; i++) { if (city[i].name.indexOf(str) !== -1) { var liEle = document.createElement("li"); liEle.shengIndex = i; liEle.innerHTML = city[i].name; //无论什么方式的添加事件都可 liEle.addEventListener("click", function (ev) { inputContent.value = this.innerHTML; inputContent.index = this.shengIndex; searchResult.style.display = "none"; }); // liEle.onclick = function (ev) { // inputContent.value = this.innerHTML; // searchResult.style.display = "none"; // } searchResult.appendChild(liEle); searchResult.style.display = "block"; } } if (inputContent.value == "") { //当文本框内容为空时,让底部div内容清空且隐藏 searchResult.innerHTML = ""; searchResult.style.display = "none"; content.innerHTML=""; topContent.innerHTML="" } }; //?????如何实现失去焦点时文本框底部div消失 search.onclick = function () { var index = inputContent.index userStor.push(city[index].child); contentClick(); } function contentClick() { for(var i=0;i<userStor[userStor.length-1].length;i++){ var spanEle = document.createElement("span"); spanEle.className = "spanEle"; spanEle.index = i; spanEle.innerHTML = userStor[userStor.length-1][i].name; spanEle.addEventListener("click",eleCLick); content.appendChild(spanEle); } } function eleCLick() { var index = this.index; var spanEle = document.createElement("span"); spanEle.className = "spanEle"; spanEle.innerHTML = this.innerHTML; var close = document.createElement("span"); close.style.marginLeft="4px"; close.style.color="red"; close.style.cursor = "pointer"; close.innerHTML="x"; close.setAttribute("data-index",userStor.length-1); close.addEventListener("click",reduce); spanEle.appendChild(close); spanEle.index = index; topContent.appendChild(spanEle); content.innerHTML=""; if(userStor[userStor.length-1][index].child==undefined){ return; } userStor.push(userStor[userStor.length-1][index].child); contentClick(); } function reduce() { content.innerHTML=""; var index = parseInt(this.getAttribute("data-index")); for(var i=index;i<topContent.children.length;i++){ topContent.children[i].remove(); i--; } console.log(userStor.length) var test = userStor.splice(index+1,userStor.length); console.log(test); console.log(index); contentClick(); } </script>
</body>
</html>
还没有评论,来说两句吧...