按照之前的约定,把之前地址选择控件进行了封装,做成了一个直接可以调用的版本,不用太多繁琐的东西,直接使用。

效果如图(跟之前一样):

这次把jquery拿掉,全部都是用js原生写的,不过动态效果还没有加进去,不过凑合能用了,弹出效果暂时还没做,主要功能性的东西做出来了,后期有时间会做一下,不过到时候就不更新文章了。

没有其他兴趣的就直接看代码。github selectAddress-v2.0

接下去进去正题。这次封装多多少少也花了点时间,平时干活完整的封装一个插件次数还是不算多,这次正好借着这个机会,慢慢一步步的摸索出来封装成插件的一种方式。

#第一步:创建基本文件,确定思路

创建项目之后,创建三个文件,分别是html,css,js文件。

这次封装的思路呢,是将js部分的声明一个对象,在对象中声明一个启动方法,把所有的逻辑部分内容放进这个启动方法里面。在调用方法弹出选择框的时候,将基本的接口数据,地址信息都传递过去,然后进行一些处理。

#第二步:构建基本页面,编写css

那么首先构建基本的页面和样式。按照之前版本样式不变,只不过html部分只有基本的按钮就行。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>chooseAddress</title><meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0,minimum-scale=1, maximum-scale=1"/><link rel="stylesheet" href="address.css">
</head>
<body>
<div class="but" onclick="show()">点击选择地址</div><div class="product_details_address" onclick="show()"><div class="choose_address jdshop_alignment_center"><div class="details_address"><div><span>送至</span><img src="https://img-blog.csdnimg.cn/2022010619580969680.png"><span id="product_address_show" style="max-width: 250px">北京市,北京市,朝阳区,建外街道</span></div></div><div class="details_stock"><img src="https://img-blog.csdnimg.cn/2022010619580976098.png"></div></div>
</div></body>
<script src="address.js"></script>
</html>

上面那部分是基本的html,加上样式

body, html {-webkit-user-select: none;user-select: none
}html {-webkit-text-size-adjust: 100%
}body {line-height: 1.6;background-color: #f5f5f9;color: #4a4a4a;font-size: 14px;font-family: Arial, '微软雅黑', Helvetica Neue, Helvetica, sans-serif;-webkit-overflow-scrolling: touch;overflow-scrolling: touch
}* {margin: 0;padding: 0
}a img {border: 0
}a {text-decoration: none;-webkit-tap-highlight-color: transparent;-webkit-appearance: none
}@font-face {font-weight: 400;font-style: normal;font-size: 14px;font-family: Arial, '微软雅黑', Helvetica Neue, Helvetica, sans-serif
}input, textarea {border: 0;outline: 0;-webkit-appearance: none;-webkit-tap-highlight-color: transparent;font-size: inherit;color: inherit
}.product_details_address {position: relative;margin: 10px;padding: 10px;border-radius: 8px;background: #fff;box-shadow: 0 2px 3px #e9e9e9;
}
.jdshop_alignment_center, .jdshop_alignment_middle, .jdshop_alignment_right, .jdshow_center_center {-webkit-box-align: center;-webkit-align-items: center;align-items: center;
}
.jdshop_alignment_bottom, .jdshop_alignment_center, .jdshop_alignment_top {-webkit-box-pack: justify;-webkit-justify-content: space-between;justify-content: space-between;
}
.jdshop_alignment_bottom, .jdshop_alignment_center, .jdshop_alignment_left, .jdshop_alignment_middle, .jdshop_alignment_right, .jdshop_alignment_top, .jdshow_center_center {display: -webkit-box;display: -webkit-flex;display: flex;
}
.details_address {display: -webkit-box;display: -webkit-flex;display: flex;-webkit-box-align: center;-webkit-align-items: center;align-items: center;
}
.product_details_address .choose_address .details_address div:first-child {height: 22px;
}
.details_address div {display: -webkit-box;display: -webkit-flex;display: flex;-webkit-box-align: center;-webkit-align-items: center;align-items: center;
}
.product_details_address .choose_address .details_address span:first-child {color: #8a8a8a;
}
.product_details_address .choose_address .details_address span {display: inline-block;color: #4a4a4a;margin-right: 10px;max-width: 170px;white-space: nowrap;text-overflow: ellipsis;overflow: hidden;
}
.product_details_address .choose_address .details_address img {width: 18px;height: 18px;margin: 2px 10px 2px 0;
}
.product_details_address .choose_address .details_address span {display: inline-block;color: #4a4a4a;margin-right: 10px;max-width: 170px;white-space: nowrap;text-overflow: ellipsis;overflow: hidden;
}
.but{margin: 0 auto;width: calc(50%);height: 30px;margin-top: 100px;background-color: lightcyan;line-height: 30px;text-align: center;font-size: 14px;
}
.jdshop_alignment_middle{-webkit-box-align: center;-webkit-align-items: center;align-items: center;-webkit-box-pack: start;-webkit-justify-content: flex-start;justify-content: flex-start;display: -webkit-box;display: -webkit-flex;display: flex;
}.yls_address_bg {position: fixed;top: 0;left: 0;height: 100%;width: 100%;background: #000;z-index: 500;opacity: .3;-webkit-transition: opacity .3s;transition: opacity .3s;touch-action: none
}
.yls_address_main {position: fixed;left: 0;width: 100%;bottom: 0;background: #fff;border-radius: 10px 10px 0 0;box-shadow: 0 0 3px #e9e9e9;-webkit-transform: translate3d(0, 120%, 0);transform: translate3d(0, 120%, 0);-webkit-transition: -webkit-transform .3s;transition: -webkit-transform .3s;transition: transform .3s;transition: transform .3s, -webkit-transform .3s;z-index: 1001;transform: translate3d(0, 0, 0);
}
.yls_address_pop_top {text-align: center;height: 50px;margin-bottom: 5px;
}
.yls_address_pop_title {height: 100%;line-height: 50px;
}
.yls_address_pop_cancel {position: absolute;right: 0;top: 0;width: 50px;height: 50px;
}
.yls_address_pop_cancel::before, .yls_address_pop_cancel::after {content: '';width: 16px;height: 1px;background: #000;display: block;position: absolute;right: 10px;top: 25px;
}
.yls_address_pop_cancel::before {transform: rotate(45deg); /*进行旋转*/
}
.yls_address_pop_cancel::after {transform: rotate(-45deg);
}
.yls_address_pop_main {}
.yls_address_product{}
.yls_address_select{height: calc(60vh);width: 100%;position: relative;overflow: hidden;
}
.yls_address_top_address{font-size: 12px;height: 35px;overflow: hidden;border-bottom: 1px solid #ddd;
}
.yls_address_top_address>div{padding: 5px 5px;margin: 0 5px;white-space: nowrap;
}
.yls_address_top_address>div.show{color: #c91623;border-bottom: #c91623 1px solid;
}
.yls_address{position: absolute;left: 0;top: 45px;overflow: auto;width: 100%;height: calc(60vh - 35px);-webkit-transform: translate3d(-100%,0,0);transform: translate3d(-100%,0,0);-webkit-transition: -webkit-transform .3s .2s;transition: -webkit-transform .3s .2s;transition: transform .3s .2s;transition: transform .3s .2s,-webkit-transform .3s .2s;
}
.yls_address p{padding: 8px 10px;font-size: 14px;
}
.yls_address p.p_show {position: relative;color: #c91623;
}
.yls_address.show {-webkit-transform: translate3d(0,0,0);transform: translate3d(0,0,0);
}

上面css部分也是包含弹出框样式的,只是弹出框部分的html没有放在页面上,而是每次弹出的时候动态添加到页面上的,这样出来的效果是这样的,没啥别的,

#第三步:了解调用方法数据结构

点击显示弹框的方法show中,需要这么写。其实这部分应该在完成整个js之后写的,不过放在前面也一样。

function show() {// 一般情况,在调用的时候,获取当前最新的地址数据,和对应的idvar startId = [1804,1805,1829,1831];var startName = ['北京市','北京市','朝阳区','朝外街道'];var url = '';//你的请求url信息//声明对象,存放请求数据url,地址信息,和需要显示最后选择地址的元素,加上一个回调方法用来获取选择完毕之后的地址。var details = {url:url,startId:startId,startName:startName,targetDom:document.getElementById('product_address_show'),fn:function () {//在点击四级地址之后回调方法中可以获取到相应的数据console.log(yls_address.CityArr);console.log(yls_address.CityIdArr);}};//调用run方法进行弹出框以及选择地址。yls_address.run(details)}

#第四步:编辑逻辑部分

####1:声明对象,声明方法

html部分的东西就这么多,上面这个其实就是使用方法,接下来是js文件的内容。有点不知道怎么分解了说了。

首先就是声明一个对象,在对象中声明一个方法。

var yls_address = {
//details就是调用的时候传进来的方法run: function (details) {}
}

####2:处理传递过来的数据,创建不同的变量赋值

接下来是先获取传过来details里面的一些数据。在run里面写

        var _this = this;//初始化idvar thisStartId = details.startId;//初始化Namevar thisStartName = details.startName;//获取请求urlvar thisUrl = details.url || '';//获取回调方法var thisFn = details.fn || '';//获取最后需要显示地址信息的元素,可有可无的var thisWrightHtml = details.targetDom || '';//因为要经常获取元素,所以把前缀单独声明了var ylsAd =  'yls_address_';var ylsTopAd =  'yls_top_address_';//判断初始数据是否正确if (thisStartName.length === thisStartName.length) {initHtml();//初始化htmlgetData(0, 1, thisStartName[0],1);//获取数据} else {console.log('初始值出问题了');}

####3:初始化弹框html,添加到页面上

initHtml()这方法就是创建html并且初始化渲染到页面上,getData方法就是调用接口获取地址数据的。接下来就是初始化方法和获取数据方法的编写了。

         /***初始化弹出框的html,去除一些样式*@method initHtml**/function initHtml() {//生成html添加到页面var thisInnerHtml = '<div class="yls_address_bg"></div>' +'<div class="yls_address_main">' +' <div class="yls_address_pop_top">' +'<div class="yls_address_pop_title">请选择地址</div>' +'<div class="yls_address_pop_cancel"></div>' +'</div>' +'<div class="yls_address_pop_main">' +'<div class="yls_address_product">' +'<div class="yls_address_select">' +'<div class="yls_address_top_address jdshop_alignment_middle">' +'<div id="yls_top_address_1">请选择</div>' +'<div id="yls_top_address_2"></div>' +'<div id="yls_top_address_3"></div>' +'<div id="yls_top_address_4"></div>' +'<div id="yls_top_address_5"></div>' +'</div>' +'<div class="yls_address" id="yls_address_1"></div>' +'<div class="yls_address" id="yls_address_2"></div>' +'<div class="yls_address" id="yls_address_3"></div>' +'<div class="yls_address" id="yls_address_4"></div>' +'<div class="yls_address" id="yls_address_5"></div>' +'</div></div></div></div>';addNode("div", thisInnerHtml, "yls_address_choose", '');for(var i = 1; i <= thisStartId.length;i++){//获取每个地址列表var ad = document.getElementById(ylsAd + i);//获取四个顶部选中的地址var topad = document.getElementById(ylsTopAd + i);//清空地址列表ad.innerHTML = '';//清空地址列表ad.className = 'yls_address';//初始化列表的样式topad.innerHTML = '';//清空选中地址的样式topad.removeAttribute('class');}}/***为页面添加html*@method addNode*@param tag 标签*@param innerHtml 标签内html*@param id 标签id*@param className 标签样式**/function addNode(tag, innerHtml, id, className) {var obj = document.createElement(tag);if (id) {obj.id = id;}if(className){obj.className=className}obj.innerHTML = innerHtml;document.body.appendChild(obj);return obj;}

####4:绑定关闭弹框事件,移除相应元素

再添加html到页面之后 并初始化,情况里面的内容,然后循环调用接口获取初始化的四级内容。不过与此同时先把背景和叉叉按钮上添加关闭弹框的点击事件,并且将移除元素的方法也写上。

         //绑定关闭按钮方法document.getElementsByClassName('yls_address_pop_cancel')[0].addEventListener("click",hideAddress,false);document.getElementsByClassName('yls_address_bg')[0].addEventListener("click",hideAddress,false);/***将数据渲染到当前列表的方法*@method remove*@param _element 删除的元素**/function remove(_element) {var _parentElement = _element.parentNode;//找到父元素,然后删除if (_parentElement) {_parentElement.removeChild(_element);}}/***隐藏弹框*@method hideAddress**/function hideAddress() {remove(document.getElementById("yls_address_choose"));}

####5:获取地址数据

获取数据方法

         /***获取地址列表数据方法*@method getData*@param areaId 点选地址的areaid*@param addressNum yls_address是第几个*@param name 是点击选择的地址name*@param isInit 是点是初始化,1是初始化,0不是初始化*@return 返回值说明*/function getData(areaId, addressNum, name, isInit){addressNum = parseInt(addressNum);//转成数字,防止变成字符串isInit = parseInt(isInit);//转成数字,防止变成字符串var addressUrl = thisUrl + areaId;//请求数据var xhr = function () {if (window.XMLHttpRequest) {return new XMLHttpRequest();}else {return new ActiveObject('Micrsorf.XMLHttp');}}();xhr.onreadystatechange = function () {if(xhr.readyState === 4 && xhr.status === 200){var res = JSON.parse(xhr.responseText);// console.log(res.result);if (isInit === 1 && addressNum < thisStartId.length) {//初始化的时候循环请求数据getData(thisStartId[addressNum - 1], (addressNum + 1), thisStartName[addressNum],1);}setPages(res.result, areaId, addressNum, name, isInit);}};xhr.open('get', addressUrl);xhr.send(null);}

####6:设置显示html,渲染页面,绑定相应的点击事件

获取数据请求全部都是用原生方法请求,然后成功获取数据之后进行循环请求,然后渲染页面方法

         /***将数据渲染到当前列表的方法*@method setPages*@param data 获取到第addressNum列的数据*@param areaId 点选地址的areaid*@param addressNum yls_address是第几个*@param name 是点击选择的地址name*@param isInit 是点是初始化,1是初始化,0不是初始化**/function setPages(data, areaId, addressNum, name, isInit) {//转成数字,防止变成字符串addressNum = parseInt(addressNum);//转成数字,防止变成字符串isInit = parseInt(isInit);//声明变量以获得当前需要做处理的列表var current = 0;isInit === 1 ? current = addressNum : current = addressNum - 1;//获取当前需要渲染的地址列表var current_address = document.getElementById(ylsAd + current);//获取当前列表选中地址的顶部tab divvar current_topAddress = document.getElementById(ylsTopAd + current);if(isInit === 1){//是初始化页面if (addressNum === thisStartId.length) {//当渲染到最后一个列表的时候,添加上show,让他显示current_address.className = 'yls_address show';current_topAddress.className = 'show';}//当前标题tab上的name添加上去current_topAddress.innerHTML = name;//为每个标题tab设置属性current_topAddress.setAttribute('areaId', thisStartId[addressNum - 1]);//为每个标题tab添加点击事件current_topAddress.addEventListener("click", function () {//获取到id上最后一位数字,然后根据数字进行相应的隐藏显示操作var areaId = this.getAttribute('areaid');var id_no = parseInt(current);//循环进行判断添加显示for (var i = 1; i < 5; i++) {var top_id = 'yls_top_address_' + i;//获取到每一个顶部tab的idvar ad_id = 'yls_address_' + i;//获取到每一个列表address的iddocument.getElementById(top_id).removeAttribute('class');document.getElementById(ad_id).className = 'yls_address';if (i === id_no) {document.getElementById(top_id).className = 'show';document.getElementById(ad_id).className = 'yls_address show';}if (i > id_no) {document.getElementById(top_id).innerHTML = '';}}//更新数据,截取到前面几位thisStartId = thisStartId.slice(0, addressNum);thisStartName = thisStartName.slice(0, addressNum);// console.log(thisStartId);}, false);//清空列表html,拼接htmlcurrent_address.innerHTML = '';//拼接html添加到div中setHtmls(current_address,data,addressNum, isInit);}else{//不是初始化页面//获取到下一级渲染列表的divvar next_address = document.getElementById(ylsAd + addressNum);//获取到要下一级列表顶部的tab divvar next_topAddress = document.getElementById(ylsTopAd + addressNum);//下一级标题显示请选择next_topAddress.innerHTML='请选择';//下一级标题添加红色样式next_topAddress.className='show';//当前标题去除红色样式current_topAddress.removeAttribute('class');//当前列表去除显示样式current_address.className = 'yls_address';//下一级列表添加显示样式next_address.className ='yls_address show';//下一级列表情况next_address.innerHTML = '';//拼接html添加到div中setHtmls(next_address,data,addressNum, isInit);}}/***拼接html,添加到div中,并且绑定点击事件*@method setHtmls*@param data 获取到第addressNum列的数据*@param faEle 需要添加html的列表div*@param addressNum yls_address是第几个*@param isInit 是点是初始化,1是初始化,0不是初始化*/function setHtmls(faEle, data, addressNum, isInit) {//拼接htmlvar html = '';if (data) {for (var i = 0; i < data.length; i++) {if ((thisStartName[addressNum - 1] === data[i].name) && isInit === 1) {html += '<p class="p_show" id="add_' + data[i].areaId + '"  addressNum="' + addressNum + '" areaId="'+data[i].areaId+'">' + data[i].name + '</p>';}else{html += '<p id="add_' + data[i].areaId + '"  addressNum="' + addressNum + '" areaId="'+data[i].areaId+'">' + data[i].name + '</p>';}}faEle.innerHTML = html;}//绑定点击事件var allP = faEle.getElementsByTagName('p');for (var j = 0; j < allP.length; j++) {allP[j].addEventListener('click', chooseAddress, false)}}

####7:实现点击地址列表中地址的方法

与此同时在方法中要为各个点击区域添加上点击事件,相应的切换四级的点击事件和具体点击选择当前列表中地址的点击事件。之后就是详细写明点击选择地址的时候触发的事件了。

         /***点击列表中的地址触发的方法*@method chooseAddress**/function chooseAddress() {//获取现在点击的城市的idvar areaId = this.getAttribute('id').split('_')[1];//获取我点击地址在第几个列表中var addressNum = parseInt(this.getAttribute('addressNum'));//获取现在点击的城市的namevar name = this.innerHTML;//更新数据// console.log(parseInt(areaId));thisStartId[addressNum-1] = parseInt(areaId);thisStartName[addressNum-1] = name;//获取当前需要渲染的地址列表var current_address = document.getElementById(ylsAd + addressNum);//获取当前列表选中地址的顶部tab divvar current_topAddress = document.getElementById(ylsTopAd + addressNum);//移除当前列表中所有的标红样式,然后添加到新选择的上面var pEles = current_address.getElementsByTagName('p');//是否对应areaId,不等于的将样式移除for(var i=0;i<pEles.length;i++){if(thisStartId[addressNum-1] === parseInt(pEles[i].getAttribute('areaId'))){pEles[i].className = 'p_show';}else{pEles[i].removeAttribute('class');}}//当前顶部tab换成点选的地址current_topAddress.innerHTML=name;//判断是否是最后一个列表,如果是,就不用请求新的数据,如果不是,就请求新的数据。if(addressNum === 4){//将文字显示到页面上thisWrightHtml.innerHTML = thisStartName;_this.CityArr = thisStartName;_this.CityIdArr = thisStartId;hideAddress();setTimeout(function () {thisFn();},300)}else{//重新请求数据getData(areaId, (addressNum+1), name, 0);}}

写的有点乱,下面我就把整个js放出来,大家要是觉得上面的乱,可以看下面一目了然的代码。

var yls_address = {run: function (details) {var _this = this;//初始化idvar thisStartId = details.startId;//初始化Namevar thisStartName = details.startName;//获取请求urlvar thisUrl = details.url || '';//获取回调方法var thisFn = details.fn || '';//获取最后需要显示地址信息的元素,可有可无的var thisWrightHtml = details.targetDom || '';//因为要经常获取元素,所以把前缀单独声明了var ylsAd =  'yls_address_';var ylsTopAd =  'yls_top_address_';//判断初始数据是否正确if (thisStartName.length === thisStartName.length) {initHtml();//初始化htmlgetData(0, 1, thisStartName[0],1);//获取数据} else {console.log('初始值出问题了');}//绑定关闭按钮方法document.getElementsByClassName('yls_address_pop_cancel')[0].addEventListener("click",hideAddress,false);document.getElementsByClassName('yls_address_bg')[0].addEventListener("click",hideAddress,false);/***初始化弹出框的html,去除一些样式*@method initHtml**/function initHtml() {//生成html添加到页面var thisInnerHtml = '<div class="yls_address_bg"></div>' +'<div class="yls_address_main">' +' <div class="yls_address_pop_top">' +'<div class="yls_address_pop_title">请选择地址</div>' +'<div class="yls_address_pop_cancel"></div>' +'</div>' +'<div class="yls_address_pop_main">' +'<div class="yls_address_product">' +'<div class="yls_address_select">' +'<div class="yls_address_top_address jdshop_alignment_middle">' +'<div id="yls_top_address_1">请选择</div>' +'<div id="yls_top_address_2"></div>' +'<div id="yls_top_address_3"></div>' +'<div id="yls_top_address_4"></div>' +'<div id="yls_top_address_5"></div>' +'</div>' +'<div class="yls_address" id="yls_address_1"></div>' +'<div class="yls_address" id="yls_address_2"></div>' +'<div class="yls_address" id="yls_address_3"></div>' +'<div class="yls_address" id="yls_address_4"></div>' +'<div class="yls_address" id="yls_address_5"></div>' +'</div></div></div></div>';addNode("div", thisInnerHtml, "yls_address_choose", '');for(var i = 1; i <= thisStartId.length;i++){//获取每个地址列表var ad = document.getElementById(ylsAd + i);//获取四个顶部选中的地址var topad = document.getElementById(ylsTopAd + i);//清空地址列表ad.innerHTML = '';//清空地址列表ad.className = 'yls_address';//初始化列表的样式topad.innerHTML = '';//清空选中地址的样式topad.removeAttribute('class');}}/***获取地址列表数据方法*@method getData*@param areaId 点选地址的areaid*@param addressNum yls_address是第几个*@param name 是点击选择的地址name*@param isInit 是点是初始化,1是初始化,0不是初始化*@return 返回值说明*/function getData(areaId, addressNum, name, isInit){addressNum = parseInt(addressNum);//转成数字,防止变成字符串isInit = parseInt(isInit);//转成数字,防止变成字符串var addressUrl = thisUrl + areaId;//请求数据var xhr = function () {if (window.XMLHttpRequest) {return new XMLHttpRequest();}else {return new ActiveObject('Micrsorf.XMLHttp');}}();xhr.onreadystatechange = function () {if(xhr.readyState === 4 && xhr.status === 200){var res = JSON.parse(xhr.responseText);// console.log(res.result);if (isInit === 1 && addressNum < thisStartId.length) {//初始化的时候循环请求数据getData(thisStartId[addressNum - 1], (addressNum + 1), thisStartName[addressNum],1);}setPages(res.result, areaId, addressNum, name, isInit);}};xhr.open('get', addressUrl);xhr.send(null);}/***将数据渲染到当前列表的方法*@method setPages*@param data 获取到第addressNum列的数据*@param areaId 点选地址的areaid*@param addressNum yls_address是第几个*@param name 是点击选择的地址name*@param isInit 是点是初始化,1是初始化,0不是初始化**/function setPages(data, areaId, addressNum, name, isInit) {//转成数字,防止变成字符串addressNum = parseInt(addressNum);//转成数字,防止变成字符串isInit = parseInt(isInit);//声明变量以获得当前需要做处理的列表var current = 0;isInit === 1 ? current = addressNum : current = addressNum - 1;//获取当前需要渲染的地址列表var current_address = document.getElementById(ylsAd + current);//获取当前列表选中地址的顶部tab divvar current_topAddress = document.getElementById(ylsTopAd + current);if(isInit === 1){//是初始化页面if (addressNum === thisStartId.length) {//当渲染到最后一个列表的时候,添加上show,让他显示current_address.className = 'yls_address show';current_topAddress.className = 'show';}//当前标题tab上的name添加上去current_topAddress.innerHTML = name;//为每个标题tab设置属性current_topAddress.setAttribute('areaId', thisStartId[addressNum - 1]);//为每个标题tab添加点击事件current_topAddress.addEventListener("click", function () {//获取到id上最后一位数字,然后根据数字进行相应的隐藏显示操作var areaId = this.getAttribute('areaid');var id_no = parseInt(current);//循环进行判断添加显示for (var i = 1; i < 5; i++) {var top_id = 'yls_top_address_' + i;//获取到每一个顶部tab的idvar ad_id = 'yls_address_' + i;//获取到每一个列表address的iddocument.getElementById(top_id).removeAttribute('class');document.getElementById(ad_id).className = 'yls_address';if (i === id_no) {document.getElementById(top_id).className = 'show';document.getElementById(ad_id).className = 'yls_address show';}if (i > id_no) {document.getElementById(top_id).innerHTML = '';}}//更新数据,截取到前面几位thisStartId = thisStartId.slice(0, addressNum);thisStartName = thisStartName.slice(0, addressNum);// console.log(thisStartId);}, false);//清空列表html,拼接htmlcurrent_address.innerHTML = '';//拼接html添加到div中setHtmls(current_address,data,addressNum, isInit);}else{//不是初始化页面//获取到下一级渲染列表的divvar next_address = document.getElementById(ylsAd + addressNum);//获取到要下一级列表顶部的tab divvar next_topAddress = document.getElementById(ylsTopAd + addressNum);//下一级标题显示请选择next_topAddress.innerHTML='请选择';//下一级标题添加红色样式next_topAddress.className='show';//当前标题去除红色样式current_topAddress.removeAttribute('class');//当前列表去除显示样式current_address.className = 'yls_address';//下一级列表添加显示样式next_address.className ='yls_address show';//下一级列表情况next_address.innerHTML = '';//拼接html添加到div中setHtmls(next_address,data,addressNum, isInit);}}/***拼接html,添加到div中,并且绑定点击事件*@method setHtmls*@param data 获取到第addressNum列的数据*@param faEle 需要添加html的列表div*@param addressNum yls_address是第几个*@param isInit 是点是初始化,1是初始化,0不是初始化*/function setHtmls(faEle, data, addressNum, isInit) {//拼接htmlvar html = '';if (data) {for (var i = 0; i < data.length; i++) {if ((thisStartName[addressNum - 1] === data[i].name) && isInit === 1) {html += '<p class="p_show" id="add_' + data[i].areaId + '"  addressNum="' + addressNum + '" areaId="'+data[i].areaId+'">' + data[i].name + '</p>';}else{html += '<p id="add_' + data[i].areaId + '"  addressNum="' + addressNum + '" areaId="'+data[i].areaId+'">' + data[i].name + '</p>';}}faEle.innerHTML = html;}//绑定点击事件var allP = faEle.getElementsByTagName('p');for (var j = 0; j < allP.length; j++) {allP[j].addEventListener('click', chooseAddress, false)}}/***点击列表中的地址触发的方法*@method chooseAddress**/function chooseAddress() {//获取现在点击的城市的idvar areaId = this.getAttribute('id').split('_')[1];//获取我点击地址在第几个列表中var addressNum = parseInt(this.getAttribute('addressNum'));//获取现在点击的城市的namevar name = this.innerHTML;//更新数据// console.log(parseInt(areaId));thisStartId[addressNum-1] = parseInt(areaId);thisStartName[addressNum-1] = name;//获取当前需要渲染的地址列表var current_address = document.getElementById(ylsAd + addressNum);//获取当前列表选中地址的顶部tab divvar current_topAddress = document.getElementById(ylsTopAd + addressNum);//移除当前列表中所有的标红样式,然后添加到新选择的上面var pEles = current_address.getElementsByTagName('p');//是否对应areaId,不等于的将样式移除for(var i=0;i<pEles.length;i++){if(thisStartId[addressNum-1] === parseInt(pEles[i].getAttribute('areaId'))){pEles[i].className = 'p_show';}else{pEles[i].removeAttribute('class');}}//当前顶部tab换成点选的地址current_topAddress.innerHTML=name;//判断是否是最后一个列表,如果是,就不用请求新的数据,如果不是,就请求新的数据。if(addressNum === 4){//将文字显示到页面上thisWrightHtml.innerHTML = thisStartName;_this.CityArr = thisStartName;_this.CityIdArr = thisStartId;hideAddress();setTimeout(function () {thisFn();},300)}else{//重新请求数据getData(areaId, (addressNum+1), name, 0);}}/***隐藏弹框*@method hideAddress**/function hideAddress() {remove(document.getElementById("yls_address_choose"));}/***为页面添加html*@method addNode*@param tag 标签*@param innerHtml 标签内html*@param id 标签id*@param className 标签样式**/function addNode(tag, innerHtml, id, className) {var obj = document.createElement(tag);if (id) {obj.id = id;}if(className){obj.className=className}obj.innerHTML = innerHtml;document.body.appendChild(obj);return obj;}/***将数据渲染到当前列表的方法*@method remove*@param _element 删除的元素**/function remove(_element) {var _parentElement = _element.parentNode;//找到父元素,然后删除if (_parentElement) {_parentElement.removeChild(_element);}}}
}

以上就是所有的代码分解,其实总的来说难度比较低,在v1.0的版本下进行封装的话就更简单了,就是把一堆东西塞进一个方法里面。看着简单点,到时候写起来也简洁一点。

调用方法在写js之前就写了,也很简单,就是把几个数据凑一块组成对象,塞进方法里面。当前2.0版本的代码还是有很多地方可以优化。不过暂时满足我项目需要,就不做太多的改动,之后要是有更新也不会更新到文章里面了。只会直接更新到github上了。

还有就是目前这个弹框还有两个问题,一个是动效还没加,一个是没有去做蒙板弹出,滑动地址列表数据的时候,底层可能也会跟着一块滚动的问题,不过解决起来不难,要是真有兴趣看到这里的朋友可以自己试一试。当然,我估计应该没啥人能看到这里了。。

同样,有什么问题可以留言讨论,大家一起进步。

OVER!

web学习笔记16-移动端地址选择功能@v2.0封装相关推荐

  1. SpringBoot学习笔记(16)----SpringBoot整合Swagger2

    Swagger 是一个规范和完整的框架,用于生成,描述,调用和可视化RESTful风格的web服务 http://swagger.io Springfox的前身是swagger-springmvc,是 ...

  2. Hadoop学习笔记—16.Pig框架学习

    Hadoop学习笔记-16.Pig框架学习 一.关于Pig:别以为猪不能干活 1.1 Pig的简介 Pig是一个基于Hadoop的大规模数据分析平台,它提供的SQL-LIKE语言叫Pig Latin, ...

  3. web学习笔记-html-html新增

    CCS学习系列笔记 web学习笔记–css(1) web学习笔记–css(2) web学习笔记–css(3) web学习笔记-html-html新增 1.html基本发展 2.h5新增的功能 3.新增 ...

  4. Linux 学习笔记16 信号量

    Linux 学习笔记16 信号量Semaphore 信号量概念 信号量(或信号灯)是一种用于提供不同进程间或一个给定进程的不同线程间同步手段的原语. 信号量是控制进程(或线程)同步(谁先执行,谁后执行 ...

  5. 区块链学习笔记16——ETH交易树和收据树

    区块链学习笔记16--ETH交易树和收据树 学习视频:北京大学肖臻老师<区块链技术与应用> 笔记参考:北京大学肖臻老师<区块链技术与应用>公开课系列笔记--目录导航页 交易树和 ...

  6. IP地址和子网划分学习笔记之《IP地址详解》

    在学习IP地址和子网划分前,必须对进制计数有一定了解,尤其是二进制和十进制之间的相互转换,对于我们掌握IP地址和子网的划分非常有帮助,可参看如下目录详文. IP地址和子网划分学习笔记相关篇章: 1.I ...

  7. java web学习笔记(持续更新)

    java web学习笔记 一.Java Web简介 二.认识Servlet 1.什么是Servlet? 2.请求路径 3.tomcat 4.Servlet的使用 三.Servlet简单应用 1.创建S ...

  8. 【论文学习笔记-16】立体匹配:360SD-net

    [论文学习笔记-16]立体匹配:360SD-net Contribution RelatedWork Method Experiment 本文利用两张360°摄像机获得的球形图片进行立体匹配,与双目立 ...

  9. cocos2d-x学习笔记16:记录存储1:CCUserDefault

    cocos2d-x学习笔记16:记录存储1:CCUserDefault 一.简述 CCUserDefalt作为NSUserDefalt类的cocos2d-x实现版本,承担了cocos2d-x引擎的记录 ...

  10. 2019年Java Web学习笔记目录

    Java Web学习笔记目录 1.Java Web学习笔记01:动态网站初体验 2.Java Web学习笔记02:在Intellij里创建Web项目 3.Java Web学习笔记03:JSP元素 4. ...

最新文章

  1. c++后台开发项目_[c/c++后台开发面经系列]4 Zoom面经(含答案)
  2. 谁的人生不迷茫?在这5句诗词里,有你想要的答案
  3. [MVC学习笔记]5.使用Controller来代替Filter完成登录验证(Session校验)
  4. 电池充放电中的C5A 的意义
  5. RH124-3 目录结构_转
  6. centos7输入法,非root用户无法使用
  7. 网络架构优化--云企业网典型场景分析for客户
  8. 04-Bootstrap的插件
  9. 【BZOJ-13361337】Alie最小圆覆盖 最小圆覆盖(随机增量法)
  10. 从0开始运行flutter helloworld笔记
  11. 数值方法求积分 详解+模板代码
  12. 【commons-beanutils专题】003- PropertyUtils 专题
  13. 卸载 Creative Cloud 桌面应用程序(macOS、Windows)
  14. 我国计算机操作系统开发历史及现状(软件学报格式的本文WORD文档在作者主页)
  15. 微博媒体碎片装订版-Arrange01
  16. matlab 纵坐标变为百分比形势,“怎么把excel纵坐标改为百分数类型“excel中如何求百分比...
  17. nyoj 366 D的小L(数的全排)
  18. sdn主要包含哪些接口_解读SDN的东西、南北向接口
  19. Unity 3D游戏开发 - U3D入门 | 3D 模型重用之预制体
  20. 数据处理笔记11 类别不平衡处理-抽样方法

热门文章

  1. opcua到mysql_基于python的opc读写和导入MSSQL/MYSQL的KepOPC中间件
  2. markdown的公式又不显示了
  3. php alt什么意思,php内部的alt内的php字符串
  4. ansys中ex是什么意思_ansys中如何查看切片图
  5. 嵌入式面试【C++】
  6. 俄总统顾问建议使用加密货币避开经济制裁
  7. android 时分秒控件,Android 实现秒转换成时分秒的方法
  8. 留学同声传译app用哪个软件好?一起来找到适合你的同声传译工具
  9. pycharm终端常用指令
  10. 右手坐标系下LookAt视图矩阵的推导