仿京东收货地址录入
京东收货地址需要通过浮动列表选择省、市、县、乡来设置,本文试用原生js实现,效果如图;

省、市、县、乡代码和名称列表在pcas-code.js文件,可以从网上下载,最新信息请看民政部网站;pcas-code.js定义一个json数组pcas,如图显示为河北省秦皇岛市北戴河区海滨镇;

代码如下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <script src="js/pcas-code.js"></script> <style type="text/css"> *, :after, :before { padding: 0px; margin: 0px; } body { padding-left: 100px; } .area-header-tips { color: #999; height: 25px; line-height: 25px; font-size: 12px; padding-left: 10px; float: left; margin-right: 7px; } .area-entrance { width: 527px; font-size: 12px; line-height: 1.6; } .area-header { float: left; position: relative; height: 23px; line-height: 23px; padding: 0 24px 0 4px; border: 1px solid #CECBCE; top: 0; background-color: #fff; } .area-header-hover { z-index: 1; height: 25px; border-bottom: 0; } .area-header-input { font-size: 12px; color: #666; overflow: hidden; } .area-header-icon { background: url(img/iconset.png) no-repeat 3px 5px; width: 17px; height: 17px; position: absolute; top: 3px; right: 4px; } .area-box { width: 460px; display: none; float: left; border: 1px solid #CECBCE; color: #005AA0; padding: 12px 12px 15px; position: absolute; top: 25px; left: 60px; box-shadow: 0 0 5px #ddd; } .area-box-hover { display: block; } .area-box-title ul { display: flex; list-style: none; padding: 0px; margin: 0px; width: 423px; height: 25px; border-bottom: 2px solid #e4393c; } .area-box-title ul li { display: none; text-align: center; background-color: #FFF; border-bottom: 0; margin-right: 4px; overflow: hidden; float: left; position: relative; } em{ font-style: normal; } .area-box-title ul li i { background: url(img/iconset.png) no-repeat 0 5px; position: absolute; right: 6px; top: 5px; display: block; width: 13px; height: 16px; overflow: hidden; opacity: .5; } .area-box-title .area-box-title-visible { display: block; height: 23px; line-height: 23px; border: 1px solid #ddd; border-bottom: 0; padding: 0 25px 1px 6px; } .area-box-title .area-box-title-current { display: block; height: 25px; line-height: 25px; border: 2px solid #e4393c; border-bottom: 0; padding: 0 25px 0 6px; } .area-box-title ul li:hover { cursor: pointer; } .area-box-content-panel { display: none; } .area-box-content-current { display: block; } .area-box-content-panel ul { list-style: none; padding-top: 10px; overflow: auto; margin-bottom: -5px; } .area-box-content-list li { padding: 0 16px 1px 0; float: left; width: 80px; line-height: 150%; display: list-item; } .area-box-content-list .long-area { width: 176px; } .area-box-content-list li:hover { color: #4a8cff; } .area-box-content-list li a { display: block; padding: 2px 4px 2px 0; color: #005aa0; text-decoration: none; } .area-box-content-list li.area-current a { color: #e4393c; } .area { position: absolute; left: 300px; top: 100px; } </style> </head> <body> <div class="area"> <div class="area-header-tips"><label>配 送 至</label></div> <div class="area-entrance" id="area-entrance"> <div class="area-header"> <span class="area-header-input"> <span class="placeholder"></span> </span> <span class="area-header-icon"></span> </div> <div class="area-box"> <div class="area-box-title"> <ul> <li><em>省</em><i></i></li> <li><em>市</em><i></i></li> <li><em>区</em><i></i></li> <li><em>街道</em><i></i></li> </ul> </div> <div class="area-box-content"> <div class="area-box-content-panel"> <ul class="area-box-content-list"> </ul> </div> <div class="area-box-content-panel"> <ul class="area-box-content-list"> </ul> </div> <div class="area-box-content-panel"> <ul class="area-box-content-list"> </ul> </div> <div class="area-box-content-panel"> <ul class="area-box-content-list"> </ul> </div> </div> </div> </div> </div> </body> <script type="text/javascript"> /* 添加事件监听函数 * obj 要添加监听的对象或元素 * eventName 事件名 * fun 监听函数的名称 * param 给监听函数传的参数, 这里就传了一个参数 */ function addEventHandler(obj, eventName, fun, param) { var fn = fun; if (param != undefined) { fn = function(e) { fun.call(this, param); //继承监听函数,并传入参数以初始化; } } if (obj.addEventListener) { // Chrome、FireFox、Opera、Safari、IE9.0及其以上版本 obj.addEventListener(eventName, fn, false); } else if (obj.attachEvent) { // IE8.0及其以下版本 obj.attachEvent('on' + eventName, fn); } else { // 早期浏览器 obj["on" + eventName] = fn; } } /* * 采用事件监听给对象绑定方法后,可以解除相应的绑定 * oTarget:监听对象 * sEventType:监听事件类型,如click,mouseover * fnHandler:监听函数 */ function removeEventHandler(oTarget, sEventType, fnHandler) { if (oTarget.removeEventListener) { // Chrome、FireFox、Opera、Safari、IE9.0及其以上版本 oTarget.removeEventListener(sEventType, fnHandler, false); } else if (oTarget.detachEvent) { // IE 8 及更早IE版本 oTarget.detachEvent("on" + sEventType, fnHandler); } else { // 早期浏览器 delete oTarget["on" + sEventType]; } } /* * 停止冒泡行为 */ function stopBubble(e) { //如果提供了事件对象,则这是一个非IE浏览器 if (e && e.stopPropagation) //因此它支持W3C的stopPropagation()方法 e.stopPropagation(); else //否则,我们需要使用IE的方式来取消事件冒泡 window.event.cancelBubble = true; } //触发点击事件 function triggerclick(obj) { //IE if (document.all) { obj.click(); } // 其它浏览器 else { var e = document.createEvent("MouseEvents"); e.initEvent("click", true, true); //这里的click可以换成你想触发的行为 obj.dispatchEvent(e); ////这里的clickME可以换成你想触发行为的DOM结点 } } //判断是否IE function _isIE() { var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串 var isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1; //判断是否IE<11浏览器 var isEdge = userAgent.indexOf("Edge") > -1 && !isIE; //判断是否IE的Edge浏览器 var isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf("rv:11.0") > -1; if (isIE) return true; else if (isEdge) //edge return true; else if (isIE11) return true; else return false; } var area_entrance = document.getElementById('area-entrance'); var area_header = area_entrance.getElementsByClassName('area-header')[0]; var area_header_tips = document.getElementsByClassName('area-header-tips')[0]; var area_header_input = area_entrance.getElementsByClassName('area-header-input')[0]; var area_box = area_entrance.getElementsByClassName('area-box')[0]; var area_box_title = area_entrance.getElementsByClassName('area-box-title')[0]; var area_box_content = area_entrance.getElementsByClassName('area-box-content')[0]; var area_box_content_panel = area_box_content.getElementsByClassName('area-box-content-panel'); var area_box_content_list = area_entrance.getElementsByClassName('area-box-content-list'); var area_current = area_entrance.getElementsByClassName('area-current'); //json格式默认收货地址 var area_address = { code: "13", name: "河北省", children: { code: "1303", name: "秦皇岛市", children: { code: "130304", name: "北戴河区", children: { code: "130304100", name: "海滨镇", } } } }; //默认收货地址文本 var default_address = ''; //默认收货地址代码 var default_province = area_address ? area_address.code : '', default_city = area_address && area_address.children ? area_address.children.code : '', default_county = area_address && area_address.children && area_address.children.children ? area_address.children.children.code : '', default_street = area_address && area_address.children && area_address.children.children && area_address.children.children.children ? area_address.children.children.children.code : ''; //中间变量 var temp_address = area_address; while (temp_address) { default_address += temp_address.name ? temp_address.name : ''; temp_address = temp_address.children; } //显示默认地址 area_header_input.children[0].innerText = default_address; //处理标题切换 function area_box_title_handle(e) { e = e || window.event; //IE window.event var t = e.target || e.srcElement; //目标对象 //标题切换 for (var i = 0; i < area_box_title.children[0].children.length; i++) { if (area_box_title.children[0].children[i] == this) { //显示当前列表 area_box_content_panel[i].classList.add('area-box-content-current'); //修改当前标题边框为红色 area_box_title.children[0].children[i].classList.remove('area-box-title-visible'); area_box_title.children[0].children[i].classList.add('area-box-title-current'); } else { //隐藏其余列表显示 area_box_content_panel[i].classList.remove('area-box-content-current'); //修改当前标题边框为灰色 area_box_title.children[0].children[i].classList.remove('area-box-title-current'); area_box_title.children[0].children[i].classList.add('area-box-title-visible'); } } } //省级标题背景变白色 area_box_title.children[0].children[0].classList.add('area-box-title-current'); //省级标题绑定点击事件 addEventHandler(area_box_title.children[0].children[0], 'click', area_box_title_handle); //显示省级列表 area_box_content_panel[0].classList.add('area-box-content-current'); //获取省级节点数组 var province = getSubLevel('0'); //添加节点到展示列表 for (var i = 0; i < province.length; i++) { //文字太长加样式 if (province[i].name.length >= 6) { area_box_content_list[0].innerHTML += '<li class="long-area"><a code=' + province[i].code + ' href="javascript:void(0)">' + province[i].name + '</a></li>'; } else { area_box_content_list[0].innerHTML += '<li><a code=' + province[i].code + ' href="javascript:void(0)">' + province[i].name + '</a></li>'; } } //每个省级节点绑定点击事件,使用事件代理 addEventHandler(area_box_content_list[0], 'click', area_box_content_list_handle, 0); //为选中省级节点触发点击事件 if (default_province) { for (var i = 0; i < area_box_content_list[0].children.length; i++) { if (area_box_content_list[0].children[i].children[0].getAttribute('code') == default_province) { triggerclick(area_box_content_list[0].children[i].children[0]); } } } //为选中市级节点触发点击事件 if (default_city) { for (var i = 0; i < area_box_content_list[1].children.length; i++) { if (area_box_content_list[1].children[i].children[0].getAttribute('code') == default_city) { triggerclick(area_box_content_list[1].children[i].children[0]); } } } //为选中区级节点触发点击事件 if (default_county) { for (var i = 0; i < area_box_content_list[2].children.length; i++) { if (area_box_content_list[2].children[i].children[0].getAttribute('code') == default_county) { triggerclick(area_box_content_list[2].children[i].children[0]); } } } //为选中街道节点触发点击事件 if (default_street) { for (var i = 0; i < area_box_content_list[3].children.length; i++) { if (area_box_content_list[3].children[i].children[0].getAttribute('code') == default_street) { triggerclick(area_box_content_list[3].children[i].children[0]); } } } //鼠标经过地址栏弹出选择列表 function area_box_hover_handle(e) { e = e || window.event; //IE window.event var t = e.target || e.srcElement; //目标对象 //地址栏宽度+左右内边距和边框-选择列表总宽度+定位左坐标 var offsetInt = Number(window.getComputedStyle(area_header).width.replace('px', '')) + 30 - 486 + 60; var offsetStr = offsetInt + 'px'; //隐藏输入框下边框 area_header.classList.add('area-header-hover'); //显示选择列表 area_box.classList.add('area-box-hover'); //根据浏览器可视区域调整 if (!(document.body.clientWidth >= 933)) { area_box.style.left = offsetStr; } else { area_box.style.left = '60px'; } //取消冒泡 stopBubble(e); //移入后绑定移出事件 addEventHandler(area_header, 'mouseout', area_box_out_handle); addEventHandler(area_box, 'mouseout', area_box_out_handle); } //地址栏绑定移入事件 addEventHandler(area_header, 'mouseover', area_box_hover_handle); //展示列表绑定移入事件 addEventHandler(area_box, 'mouseover', area_box_hover_handle); //关闭选择列表 function area_box_out_handle() { //去除类别标识 //显示输入框下边框 area_header.classList.remove('area-header-hover'); //隐藏选择列表 area_box.classList.remove('area-box-hover'); } //本级节点绑定点击事件 function area_box_content_list_handle(index, e) { e = e || window.event; //IE window.event var t = e.target || e.srcElement; //目标对象 //点击上级节点不处理,2020-01-03 if (t.tagName != 'A') return; var tli = t.parentElement; var arrSubLevel = getSubLevel(t.getAttribute('code')); var fillContent = ''; //取消移出事件 removeEventHandler(area_header, 'mouseout', area_box_out_handle); removeEventHandler(area_box, 'mouseout', area_box_out_handle); //当前选择节点变红色 for (var i = 0; i < area_box_content_list[index].children.length; i++) { if (area_box_content_list[index].children[i] == tli) { tli.classList.add('area-current'); } else { area_box_content_list[index].children[i].classList.remove('area-current'); } } //本级标题改为所选地址 if (_isIE()) { //IE浏览器不支持display:flex属性,支持float,截取五个汉字,以免超长无法显示 area_box_title.children[0].children[index].innerHTML ='<em>'+ t.innerText.substring(0, 5)+'</em><i></i>'; } else { //其余浏览器支持display:flex属性,自动截短 area_box_title.children[0].children[index].innerHTML ='<em>'+t.innerText+'</em><i></i>'; } //点击街道退出 if (index == 3) { //选中地址填充到输入框 for (var i = 0; i < area_current.length; i++) { fillContent += area_current[i].children[0].innerText; } area_header_input.innerHTML = fillContent; //关闭弹窗 area_box_out_handle(); //取消冒泡 stopBubble(e); return; } //本级标题变色 area_box_title.children[0].children[index].classList.remove('area-box-title-current'); area_box_title.children[0].children[index].classList.add('area-box-title-visible'); //次级标题改为'请选择' area_box_title.children[0].children[index + 1].innerHTML = '<em>'+'请选择'+'</em><i></i>'; //次级标题显示 // area_box_title.children[0].children[index + 1].classList.add('area-box-title-visible'); //次级标题变色 area_box_title.children[0].children[index + 1].classList.add('area-box-title-current'); //次级标题绑定点击事件 if (area_box_title.children[0].children.length > index + 1) { addEventHandler(area_box_title.children[0].children[index + 1], 'click', area_box_title_handle); } //取消后续标题绑定点击事件 for (var i = area_box_title.children[0].children.length - 1; i > index + 1; i--) { removeEventHandler(area_box_title.children[0].children[i], 'click', area_box_title_handle); //隐藏后续标题 area_box_title.children[0].children[i].classList.remove('area-box-title-visible'); } //切换显示选择列表 area_box_content_panel[index].classList.remove('area-box-content-current'); area_box_content_panel[index + 1].classList.add('area-box-content-current'); //填充次级可选节点,首先清空 area_box_content_panel[index + 1].children[0].innerHTML = ''; for (var i = 0; i < arrSubLevel.length; i++) { //文字太长加样式 if (arrSubLevel[i].name.length >= 6) { area_box_content_panel[index + 1].children[0].innerHTML += '<li class="long-area"><a code=' + arrSubLevel[i].code + ' href="javascript:void(0)">' + arrSubLevel[i].name + '</a></li>'; } else { area_box_content_panel[index + 1].children[0].innerHTML += '<li><a code=' + arrSubLevel[i].code + ' href="javascript:void(0)">' + arrSubLevel[i].name + '</a></li>'; } } //为上级节点绑定次级可选节点点击事件,2020-01-03 addEventHandler(area_box_content_panel[index + 1], 'click', area_box_content_list_handle, index + 1); } //根据所选地址code查找子级节点,返回数组,找不到返回undefined function getSubLevel(code) { var cities, areas, streets, rValue; if (!code) { return; } //点击地址栏,返回所有节点 if (code == '0') { rValue = pcas; return rValue; } //点击省级节点,返回市级列表数组 for (var i = 0; i < pcas.length; i++) { if (pcas[i].code == code) { //刚好是省级节点 rValue = pcas[i].children; return rValue; } else if (pcas[i].code == code.substring(0, 2)) { //前两位是省级节点 cities = pcas[i].children; break; } } //点击市级节点,返回区级列表数组 if (cities) { for (var i = 0; i < cities.length; i++) { if (cities[i].code == code) { rValue = cities[i].children; return rValue; } else if (cities[i].code == code.substring(0, 4)) { areas = cities[i].children; break; } } } //点击区县级节点,返回街道列表数组 if (areas) { for (var i = 0; i < areas.length; i++) { if (areas[i].code == code) { rValue = areas[i].children; return rValue; } else if (areas[i].code == code.substring(0, 6)) { streets = areas[i].children; break; } } } return rValue; } </script> </html>

浙公网安备 33010602011771号