原生js实现地址选择组件(三级联动)
时间:2022-09-04 01:00:00
1.实现效果
2.实现步骤
首先引入地址json数据、省、市、三级联动demo展示省市两级联动,三级联动也是如此。
样式可以自定义。
<section class="mySetting"> <div class="dialog" id="areaDialog"> <div class="flex-row j_b a_title"> <p>更换区域</p> </div> <div class="flex-row tab_switch"> <p class="active">请选择省份</p> <p>请选择城市</p> </div> <div class="list_content"> <div class="list flex" id="provinceList"></div> <div class="list flex" id="cityList"></div> </div> </div> </section>
.flex {
display: flex; } .flex-row {
display: flex; align-items: center; } body {
padding: 0; margin: 0; height: 100vh; display: flex; justify-content: center;
align-items: center;
}
div {
box-sizing: border-box;
}
.dialog {
width: 811px;
background-image: linear-gradient(-225deg, #9EFBD3 0%, #57E9F2 48%, #45D4FB 100%);
border-radius: 4px;
padding: 30px 40px 57px;
}
.mySetting #areaDialog .tab_switch {
margin-top: 20px;
}
.mySetting #areaDialog .tab_switch p {
width: 80px;
font-size: 16px;
color: #333333;
margin-right: 60px;
font-weight: 600;
user-select: none;
}
.mySetting #areaDialog .tab_switch .active {
position: relative;
}
.mySetting #areaDialog .tab_switch .active::after {
content: '';
width: 62px;
height: 4px;
background: #00557f;
border-radius: 90px;
position: absolute;
left: 50%;
margin-left: -31px;
bottom: -6px;
}
.mySetting #areaDialog .list_content {
width: 100%;
height: 398px;
background: #fff;
margin: 20px 0;
overflow: hidden;
overflow-y: scroll;
scrollbar-width: none;
padding: 30px 30px 48px;
border-radius: 20px;
}
.mySetting #areaDialog .list_content::-webkit-scrollbar {
width: 5px;
height: 5px;
}
.mySetting #areaDialog .list_content::-webkit-scrollbar-track {
background: #ecdeff;
border-radius: 2px;
}
.mySetting #areaDialog .list_content::-webkit-scrollbar-thumb {
background: #d2eaff;
border-radius: 10px;
}
.mySetting #areaDialog .list_content .list {
flex-wrap: wrap;
}
.mySetting #areaDialog .list_content .list p {
width: 129px;
padding: 0 5px;
height: 57px;
border: 1px solid #D4D4D4;
font-size: 15px;
color: #707070;
margin-right: 30px;
text-align: center;
user-select: none;
margin-bottom: 30px;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
}
.mySetting #areaDialog .list_content .list p:nth-child(4n+4) {
margin-right: 0;
}
.mySetting #areaDialog .list_content .list .pro_active {
position: relative;
border: 1px solid #45D4FB;
}
.mySetting #areaDialog .list_content .list .pro_active::after {
position: absolute;
content: '';
width: 40px;
height: 42px;
background: url(img/角标选中.png);
background-size: 100% 100%;
top: 21px;
right: -5px;
}
原生js逻辑:
var province = '',
city = '',
cityItem = '';
// 省列表
function renderP() {
var content = "";
provinceList.forEach((item, index) => {
content += ''
+ item.name +
' '
})
document.getElementById("provinceList").innerHTML = content;
// 选择省
var items = document.getElementById("provinceList").getElementsByTagName("p");
var length = items.length;
for (var i = 0; i < length; i++) {
items[i].onclick = function() {
for (var j = 0; j < length; j++) {
items[j].classList.remove('pro_active');
};
this.classList.add('pro_active');
province = this.dataset.name;
cityItem = this.dataset.index;
}
};
}
renderP();
// 城市列表
function renderCity() {
var content = "";
provinceList[cityItem].cityList.forEach((item, index) => {
content += ''
+ item.name + ' '
})
document.getElementById("cityList").innerHTML = content;
// 选择城市
var items = document.getElementById("cityList").getElementsByTagName("p");
var length = items.length;
for (var i = 0; i < length; i++) {
items[i].onclick = function() {
for (var j = 0; j < length; j++) {
items[j].classList.remove('pro_active');
};
this.classList.add('pro_active');
city = this.dataset.name;
}
};
}
var items = document.getElementsByClassName('tab_switch')[0].getElementsByTagName('p');
// 切换地区选择
for (var i in items) {
items[i].index = i;
items[i].onclick = function() {
if (this.index == 0) {
document.getElementById('provinceList').style.display = 'flex';
document.getElementById('cityList').style.display = 'none';
} else {
if (province == '' || province == undefined || province == null) {
return false;
}
document.getElementById('provinceList').style.display = 'none';
document.getElementById('cityList').style.display = 'flex';
renderCity();
}
for (var j = 0; j < items.length; j++) {
items[j].classList.remove('active');
};
this.classList.add('active');
}
}
jquery写法:
// jq写法
function renderP() {
$.each(provinceList, function(n, item) {
content = ''
+ item.name + ' '
$("#provinceList").append(content);
})
// 选择省
$('#provinceList p').click(function() {
$(this).addClass("pro_active").siblings().removeClass("pro_active");
province = $(this).attr('data-name')
cityItem = $(this).attr('data-index')
});
}
renderP();
// 城市列表
function renderCity() {
$.each(provinceList[cityItem].cityList, function(n, item) {
content = ''
+ item.name + ' '
$("#cityList").append(content);
})
// 选择城市
$('#cityList p').click(function() {
$(this).addClass("pro_active").siblings().removeClass("pro_active");
city = $(this).attr('data-name');
});
}
// 切换地区选择
$('#areaDialog .tab_switch p').click(function() {
if ($(this).index() == 0) {
// renderP();
$("#provinceList").fadeIn(300)
$("#cityList").fadeOut(100)
} else {
if (province == '' || province == undefined || province == null) {
return false;
}
// 清空数据重新渲染
$("#cityList").empty()
renderCity();
$("#provinceList").fadeOut(100)
$("#cityList").fadeIn(300)
}
$(this).addClass("active").siblings().removeClass("active");
});
附地址jso数据:
var provinceList = [
{
name: '北京市', cityList: [
{
name: '市辖区', areaList: ["东城区", "西城区", "朝阳区", "丰台区", "石景山区", "海淀区", "门头沟区", "房山区", "通州区", "顺义区", "昌平区", "大兴区", "怀柔区", "平谷区", "密云区", "延庆区", "其他区"] },
]
},
{
name: '天津市', cityList: [
{
name: '市辖区', areaList: ["和平区", "河东区", "河西区", "南开区", "河北区", "红桥区", "东丽区", "西青区", "津南区", "北辰区", "武清区", "宝坻区", "滨海新区", "宁河区", "静海区", "蓟州区", "其他区"] },
]
},
{
name: '上海市', cityList: [
{
name: '市辖区', areaList: ["黄浦区", "徐汇区", "长宁区", "静安区", "普陀区", "虹口区", "杨浦区", "闵行区", "宝山区", "嘉定区", "浦东新区", "金山区", "松江区", "青浦区", "奉贤区", "崇明区", "其他区"] },
]
},
{
name: '重庆市', cityList: [
{
name: '市辖区', areaList: ["万州区", "涪陵区", "渝中区", "大渡口区", "江北区", "沙坪坝区", "九龙坡区", "南岸区", "北碚区", "綦江区", "大足区", "渝北区", "巴南区", "黔江区", "长寿区", "江津区", "合川区", "永川区", "南川区", "璧山区", "铜梁区", "潼南区", "荣昌区", "开州区", "梁平区", "武隆区", "其他区"] },
{
name: '县', areaList: ["城口县", "丰都县", "垫江县", "忠县", "云阳县", "奉节县", "巫山县", "巫溪县", "石柱土家族自治县", "秀山土家族苗族自治县", "酉阳土家族苗族自治县", "彭水苗族土家族自治县"] },
]
},
{
name: '河北省', cityList: [
{
name: '石家庄市', areaList: ["长安区", "桥西区", "新华区", "井陉矿区", "裕华区", "藁城区", "鹿泉区", "栾城区", "井陉县", "正定县", "行唐县", "灵寿县", "高邑县", "深泽县", "赞皇县", "无极县", "平山县", "元氏县", "赵县", "石家庄高新技术产业开发区", "石家庄循环化工园区", "辛集市", "晋州市", "新乐市", "其他区"] },
{
name: '唐山市', areaList: ["路南区", "路北区", "古冶区", "开平区", "丰南区", "丰润区", "曹妃甸区", "滦县", "滦南县", "乐亭县", "迁西县", "玉田县", "唐山市芦台经济技术开发区", "唐山市汉沽管理区", "唐山高新技术产业开发区", "河北唐山海港经济开发区", "遵化市", "迁安市", "其他区"] },
{
name: '秦皇岛市', areaList: ["海港区", "山海关区", "北戴河区", "抚宁区", "青龙满族自治县", "昌黎县", "卢龙县", "秦皇岛市经济技术开发区", "北戴河新区",