按照以前的約定,把以前地址選擇控件進行了封裝,作成了一個直接能夠調用的版本,不用太多繁瑣的東西,直接使用。css
效果如圖(跟以前同樣):html
此次把jquery拿掉,所有都是用js原生寫的,不過動態效果尚未加進去,不過湊合能用了,彈出效果暫時還沒作,主要功能性的東西作出來了,後期有時間會作一下,不過到時候就不更新文章了。jquery
沒有其餘興趣的就直接看代碼。github selectAddress-v2.0git
接下去進去正題。此次封裝多多少少也花了點時間,平時幹活完整的封裝一個插件次數仍是不算多,此次正好藉着這個機會,慢慢一步步的摸索出來封裝成插件的一種方式。github
建立項目以後,建立三個文件,分別是html,css,js文件。web
此次封裝的思路呢,是將js部分的聲明一個對象,在對象中聲明一個啓動方法,把全部的邏輯部份內容放進這個啓動方法裏面。在調用方法彈出選擇框的時候,將基本的接口數據,地址信息都傳遞過去,而後進行一些處理。數據結構
那麼首先構建基本的頁面和樣式。按照以前版本樣式不變,只不過html部分只有基本的按鈕就行。app
<!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="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAMAAAApB0NrAAABj1BMVEUAAAD////mABKcAQ3mABLDABDFABDmABK+AQ++ARDmABLCABDmABLNABDCABDmABK+AQ/mABK8AQ++AQ/mABLMABC/ARDmABK8AQ/mABLiABK+AQ/mABK7AQ+6AQ/mABLmABK6AQ/mABK9AQ/mABK6AQ/XABHmABK6AQ++Dxy+EB2/FCHAFiPAFyTBABDCHyvDChnDIy/EJTHJOUTJOkXKPUfLP0nNRlDPTlfQVF3RV2DTX2fWABHXa3PZcnnad37cJDPcf4beho3fh47gi5LgjpXhj5bjABLkWGPlDyDlnqTmABLmARPmAhTmoafnparnpqvoEyToFiboGCjpGyvprLHprrPqJDPqKDfqKzrrMD/rMUDsUV3tRlPtR1TtvsLugYnuwsbvXWjvxMfwZnHwtLnxbnjxzM/xzdDyeoPy0NP0i5P0jpb0kpr1m6L3sbf3tLn34eP4vMH55+j56uv70tX78PH86uv87/D95uj96uv99/f9+fn+8vP+8/T++/v+/Pz+/f3/+/v//v7////fwfveAAAAKHRSTlMAAAIDCw0NDhERFRlCSEtdaXiFhYiQlKi0wMHJytLT5Obp6erq7vz8QGVO8AAAAbRJREFUOMuF1OVfAjEYB3BAFEUUURSxAIvZ3d0xsbvF7u6W+8Pdc8/dbQcov1e77ftZ3TaDMXYMRoMWk83p9vqp3+t22ky8WjAWh4fyeByWSGMvpPoU28OM2UUj4zKLxpqnVAdWNjeWJ1SUZ+XGrJC58xeJ5fl0RkVmzSgDBT8kJU/r6nCqseP3nsTzPaogOxoLrmj1RzDSa6+yOotsHPh1gx0cnYTkwkInVjvAmHDrluSWnRpC6g+hFKpC5DExY0N/AA23ZYSl8gHKHQSRjRknmjOoHyJyxqHcRxA5mXGjuYD6HjT9UB4kiNzMeNEcQ/0imi0odxFEXmb8aNbkibZAQ5s8/TqCyM+M+nPuoeFtoKl5+EteIXbJEO+HBiVdWhVDSvl8aOBeJLsqIUV8XZRuiqZBM7l8f1guOZnUCMni+8wy/66SuwpuUvn/0p2Odk58ccJ/Z5m4QjLFCckQzw9k9hHIdTknJYm6cwjZYIfns1HoJi3sPEO2JalbINkR9wJ2cn9aIPkJUe4XpWO1nBQk/3FPR6q1geLD73txGCpJ++/dAORLT4rytgjvT05miv79iZ1ftLMHLKmtwx4AAAAASUVORK5CYII="> <span id="product_address_show" style="max-width: 250px">北京市,北京市,朝陽區,建外街道</span></div> </div> <div class="details_stock"> <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADgAAAA4CAMAAACfWMssAAABMlBMVEX///+KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopnwFdMAAAAZXRSTlMAAQIDBAYHCgsMDg8UFRYYGhweJCYpLS4wMzc9QUJHSElLTlBUWltgZmhpcHF1d3t9gIGEhoiJi42TlpeZn6Gkpqesra6ytLm+v8THycvP0NLT1Nrc3+Pk5+jr7fDx8vP19vr9/vBx0x4AAAENSURBVBgZ7cFVVkIBFAXQ80RERVCxsbC7uxPEQrFb4XnmPwXvHcLhy7V0b/z77QauGlGBqoVvXsagy9IcRyAbp1uHbpVuErLgkCbMQBY7p/nshCx5T/PQBFnbG02hDrKeMk0uAtkY3QZ0S3RTkAX7NOEgZDVnNF9dkDXc0jylIGt9pbmuh6y7THNSDdkI3TZ083QzkAW7dMOQRU9pSmnI+uhuoGp/oXnvgKjlmeYjDVHqkabUC1HzHU05A1GiSBMOQRQv0ISjENVe0E1AFMvTTUMUzdHNQRQ5oluBKNij24Qo2KLbCSBaozuIQLRIl41CNEuXj0I0SXcWg2qZ5iIO3XjIYgKV6C8k8e+P+AHSCVwAt/Q8GwAAAABJRU5ErkJggg=="> </div> </div> </div> </body> <script src="address.js"></script> </html>
上面那部分是基本的html,加上樣式ide
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沒有放在頁面上,而是每次彈出的時候動態添加到頁面上的,這樣出來的效果是這樣的,沒啥別的,flex
點擊顯示彈框的方法show中,須要這麼寫。其實這部分應該在完成整個js以後寫的,不過放在前面也同樣。
function show() { // 通常狀況,在調用的時候,獲取當前最新的地址數據,和對應的id var 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) }
html部分的東西就這麼多,上面這個其實就是使用方法,接下來是js文件的內容。有點不知道怎麼分解了說了。
首先就是聲明一個對象,在對象中聲明一個方法。
var yls_address = { //details就是調用的時候傳進來的方法 run: function (details) { } }
接下來是先獲取傳過來details裏面的一些數據。在run裏面寫
var _this = this; //初始化id var thisStartId = details.startId; //初始化Name var thisStartName = details.startName; //獲取請求url var 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();//初始化html getData(0, 1, thisStartName[0],1);//獲取數據 } else { console.log('初始值出問題了'); }
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; }
再添加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")); }
獲取數據方法
/** * 獲取地址列表數據方法 * @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 div var 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的id var ad_id = 'yls_address_' + i;//獲取到每個列表address的id document.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,拼接html current_address.innerHTML = ''; //拼接html添加到div中 setHtmls(current_address,data,addressNum, isInit); }else{ //不是初始化頁面 //獲取到下一級渲染列表的div var next_address = document.getElementById(ylsAd + addressNum); //獲取到要下一級列表頂部的tab div var 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) { //拼接html var 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() { //獲取如今點擊的城市的id var areaId = this.getAttribute('id').split('_')[1]; //獲取我點擊地址在第幾個列表中 var addressNum = parseInt(this.getAttribute('addressNum')); //獲取如今點擊的城市的name var name = this.innerHTML; //更新數據 // console.log(parseInt(areaId)); thisStartId[addressNum-1] = parseInt(areaId); thisStartName[addressNum-1] = name; //獲取當前須要渲染的地址列表 var current_address = document.getElementById(ylsAd + addressNum); //獲取當前列表選中地址的頂部tab div var 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; //初始化id var thisStartId = details.startId; //初始化Name var thisStartName = details.startName; //獲取請求url var 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();//初始化html getData(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 div var 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的id var ad_id = 'yls_address_' + i;//獲取到每個列表address的id document.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,拼接html current_address.innerHTML = ''; //拼接html添加到div中 setHtmls(current_address,data,addressNum, isInit); }else{ //不是初始化頁面 //獲取到下一級渲染列表的div var next_address = document.getElementById(ylsAd + addressNum); //獲取到要下一級列表頂部的tab div var 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) { //拼接html var 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() { //獲取如今點擊的城市的id var areaId = this.getAttribute('id').split('_')[1]; //獲取我點擊地址在第幾個列表中 var addressNum = parseInt(this.getAttribute('addressNum')); //獲取如今點擊的城市的name var name = this.innerHTML; //更新數據 // console.log(parseInt(areaId)); thisStartId[addressNum-1] = parseInt(areaId); thisStartName[addressNum-1] = name; //獲取當前須要渲染的地址列表 var current_address = document.getElementById(ylsAd + addressNum); //獲取當前列表選中地址的頂部tab div var 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!