加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 创业 > C语言 > 正文

四级地址插件升级改造(京东商城地址选择插件)city-picker

发布时间:2020-12-15 02:11:45 所属栏目:C语言 来源:网络整理
导读:最近公司做的项目要和京东的数据做对接,所以要做个类似京东商品的详情页。页面的数据,是可以从京东接口获取到的,但是地址插件选择的效果需要自己实现。前端的同事在之前的项目中,已经选择了一款地址插件(city-picker.js),但是这款插件最多只支持三级地

最近公司做的项目要和京东的数据做对接,所以要做个类似京东商品的详情页。页面的数据,是可以从京东接口获取到的,但是地址插件选择的效果需要自己实现。前端的同事在之前的项目中,已经选择了一款地址插件(city-picker.js),但是这款插件最多只支持三级地址,而且最主要的是这插件的地址数据来源,是写死在一个json文件中的,意思就是说,在使用这个插件的时候页面要一次性的把所有的地址数据都加载出来,这在pc端一般倒还可以承受,但是到了,移动端,随便一个手机就会卡死,浏览器直接崩溃。

经过在网上的各种查找,和研究,发现一个博客,http://www.cnblogs.com/huangchanghuan/p/6681510.html

对city-picker这个插件进行了扩展,扩展成了支持四级地址的插件了。这正是我想要的,因为京东给过来的地址数据就是4级的。正好可以使用。然后就拿过来直接用了。

很强大,完美的满足了,我的需求。但是这个大神的博客只是将三级地址改造成了四级地址,没有解决,动态加载数据的问题,就是说用这个四级地址插件的时候,还是要把京东的地址库数据转成json文件一次性加载到页面。这样的话在移动端浏览时还是会把浏览器搞崩。

好了,说了这么多铺垫的废话,就是为了引出,我对这个四级地址插件的改造。

直接代码

  1 /*!
  2  * CityPicker v@VERSION
  3  * https://github.com/tshi0912/citypicker
  4  *
  5  * Copyright (c) 2015-@YEAR Tao Shi
  6  * Released under the MIT license
  7   8  * Date: @DATE
  9  */
 10 
 11 
 12 ChineseDistricts={
 13     "86": {
 14         "中国": [
 15             {
 16                 "address": "北京",17                 "code": "1"
 18             },19             {
 20                 "address": "上海",21                 "code": "2"
 22             },23             {
 24                 "address": "天津",25                 "code": "3"
 26             },27             {
 28                 "address": "重庆",29                 "code": "4"
 30             },31             {
 32                 "address": "河北",33                 "code": "5"
 34             },35             {
 36                 "address": "山西",37                 "code": "6"
 38             },39             {
 40                 "address": "河南",41                 "code": "7"
 42             },43             {
 44                 "address": "辽宁",45                 "code": "8"
 46             },47             {
 48                 "address": "吉林",49                 "code": "9"
 50             },51             {
 52                 "address": "黑龙江",53                 "code": "10"
 54             },55             {
 56                 "address": "内蒙古",57                 "code": "11"
 58             },59             {
 60                 "address": "江苏",61                 "code": "12"
 62             },63             {
 64                 "address": "山东",65                 "code": "13"
 66             },67             {
 68                 "address": "安徽",69                 "code": "14"
 70             },71             {
 72                 "address": "浙江",73                 "code": "15"
 74             },75             {
 76                 "address": "福建",77                 "code": "16"
 78             },79             {
 80                 "address": "湖北",81                 "code": "17"
 82             },83             {
 84                 "address": "湖南",85                 "code": "18"
 86             },87             {
 88                 "address": "广东",89                 "code": "19"
 90             },91             {
 92                 "address": "广西",93                 "code": "20"
 94             },95             {
 96                 "address": "江西",97                 "code": "21"
 98             },99             {
100                 "address": "四川",101                 "code": "22"
102             },103             {
104                 "address": "海南",105                 "code": "23"
106             },107             {
108                 "address": "贵州",109                 "code": "24"
110             },111             {
112                 "address": "云南",113                 "code": "25"
114             },115             {
116                 "address": "西藏",117                 "code": "26"
118             },119             {
120                 "address": "陕西",121                 "code": "27"
122             },123             {
124                 "address": "甘肃",125                 "code": "28"
126             },127             {
128                 "address": "青海",129                 "code": "29"
130             },131             {
132                 "address": "宁夏",133                 "code": "30"
134             },135             {
136                 "address": "新疆",137                 "code": "31"
138             },139             {
140                 "address": "台湾",141                 "code": "32"
142             },143             {
144                 "address": "钓鱼岛",145                 "code": "84"
146             },147             {
148                 "address": "港澳",149                 "code": "52993"
150             }
151         ]
152     }
153 };
154 
155 (function (factory) {
156     if (typeof define === 'function' && define.amd) {
157         // AMD. Register as anonymous module.
158         define(['jquery','ChineseDistricts'],factory);
159     } else typeof exports === 'object') {
160          Node / CommonJS
161         factory(require('jquery'),require('ChineseDistricts'));
162     } else {
163          Browser globals.
164         factory(jQuery,ChineseDistricts);
165     }
166 })( ($,ChineseDistricts) {
167 
168     'use strict';
169     typeof ChineseDistricts === 'undefined'170         throw new Error('The file "city-picker.data.js" must be included first!');
171 172     var NAMESPACE = 'citypicker'173     var EVENT_CHANGE = 'change.' + NAMESPACE;
174     var PROVINCE = 'province'175     var CITY = 'city'176     var DISTRICT = 'district'177     var COUNTY = 'county'178 
179      CityPicker(element,options) {
180         this.$element = $(element);
181         this.$dropdown = null182         this.options = $.extend({},CityPicker.DEFAULTS,$.isPlainObject(options) && options);
183         this.active = false184         this.dems = [];
185         this.needBlur = 186         this.init();
187 188 
189     CityPicker.prototype =190         constructor: CityPicker,191 
192         init:  () {
193 
194             .defineDems();
195 
196             .render();
197 
198             .bind();
199 
200             true201         },1)">202         界面显示处理
203         render: 204             var p = .getPosition(),1)">205                 placeholder = this.$element.attr('placeholder') || .options.placeholder,1)">206                 textspan = '<span class="city-picker-span" style="' +
207                     this.getWidthStyle(p.width) + 'height:' +
208                     p.height + 'px;line-height:' + (p.height - 1) + 'px;">' +
209                     (placeholder ? '<span class="placeholder">' + placeholder + '</span>' : '') +
210                     '<span class="title"></span><div class="arrow"></div>' + '</span>',1)">211 
212                 dropdown = '<div class="city-picker-dropdown" style="left:0px;top:100%;' +
213                     this.getWidthStyle(p.width,true) + '">' +
214                     '<div class="city-select-wrap">' +
215                     '<div class="city-select-tab">' +
216                     '<a class="active" data-count="province">省份</a>' +
217                     (this.includeDem('city') ? '<a data-count="city">城市</a>' : '') +
218                     (this.includeDem('district') ? '<a data-count="district">区县</a>' : '') +
219                     (this.includeDem('county') ? '<a data-count="county">乡镇</a>' : '') +
220                     '</div>' +
221                     '<div class="city-select-content">' +
222                     '<div class="city-select province" data-count="province"></div>' +
223                     (this.includeDem('city') ? '<div class="city-select city" data-count="city"></div>' : '') +
224                     (this.includeDem('district') ? '<div class="city-select district" data-count="district"></div>' : '') +
225                     (this.includeDem('county') ? '<div class="city-select county" data-count="county"></div>' : '') +
226                     '</div></div>'227 
228             this.$element.addClass('city-picker-input'229             this.$textspan = $(textspan).insertAfter(.$element);
230             this.$dropdown = $(dropdown).insertAfter(.$textspan);
231             var $select = this.$dropdown.find('.city-select'232 
233              setup this.$province,this.$city and/or this.$district object
234             $.each(this.dems,$.proxy( (i,type) {
235                 this['$' + type] = $select.filter('.' + type + ''236             },1)">237 
238             .refresh();
239 240 
241         refresh:  (force) {
242              clean the data-item for each $select
243             244             $select.data('item',1)">245              parse value from value of the target $element
246             var val = this.$element.val() || ''247             val = val.split('/'248             $.each(function (i,type) {遍历dems
249                 if (val[i] && i < val.length) {
250                     this.options[type] = val[i];把当前显示值赋值给options
251                 } if252                     this.options[type] = ''253                 }
254                 this.output(type);输出下拉框显示数据
255             },1)">256             .tab(PROVINCE);
257             this.feedText();界面显示选择的内容
258             this.feedVal();input标签value赋值
259 260         dems赋值
261         defineDems: 262             var stop = 263             $.each([PROVINCE,CITY,DISTRICT,COUNTY],1)">264                 if (!stop) {
265                     .dems.push(type);
266 267                 if (type === .options.level) {
268                     stop = 269 270             },1)">271 272 
273         includeDem:  (type) {
274             return $.inArray(type,1)">this.dems) !== -1275 276 
277         getPosition: 278             var p,h,w,s,pw;
279             p = .$element.position();
280             s = this.getSize(281             h = s.height;
282             w = s.width;
283             .options.responsive) {
284                 pw = .$element.offsetParent().width();
285                  (pw) {
286                     w = w / pw;
287                     if (w > 0.99288                         w = 1289                     }
290                     w = w * 100 + '%'291 292             }
293 
294             return295                 top: p.top || 0296                 left: p.left || 0297                 height: h,1)">298                 width: w
299             };
300 301 
302         getSize:  ($dom) {
303              $wrap,$clone,sizes;
304             if (!$dom.is(':visible')) {
305                 $wrap = $("<div />").appendTo($("body"306                 $wrap.css({
307                     "position": "absolute !important"308                     "visibility": "hidden !important"309                     "display": "block !important"
310                 });
311 
312                 $clone = $dom.clone().appendTo($wrap);
313 
314                 sizes =315                     width: $clone.outerWidth(),1)">316                     height: $clone.outerHeight()
317                 };
318 
319                 $wrap.remove();
320             } 321                 sizes =322                     width: $dom.outerWidth(),1)">323                     height: $dom.outerHeight()
324 325 326 
327              sizes;
328 329 
330         getWidthStyle:  (w,dropdown) {
331             this.options.responsive && !$.isNumeric(w)) {
332                 return 'width:' + w + ';'333             } 334                 return 'width:' + (dropdown ? Math.max(320,w) : w) + 'px;'335 336 337         绑定事件
338         bind: 339             var $this = 340             $(document).on('click',(this._mouteclick =  (e) {
341                 var $target = $(e.target);
342                  $dropdown,$span,$input;
343                 if ($target.is('.city-picker-span'344                     $span = $target;
345                 } if ($target.is('.city-picker-span *'346                     $span = $target.parents('.city-picker-span'347 348                 if ($target.is('.city-picker-input'349                     $input =350 351                 if ($target.is('.city-picker-dropdown'352                     $dropdown =353                 } if ($target.is('.city-picker-dropdown *'354                     $dropdown = $target.parents('.city-picker-dropdown'355 356                 if ((!$input && !$span && !$dropdown) ||
357                     ($span && $span.get(0) !== $this.$textspan.get(0)) ||
358                     ($input && $input.get(0) !== $this.$element.get(0)) ||
359                     ($dropdown && $dropdown.get(0) !== $this.$dropdown.get(0))) {
360                     $this.close(361 362             }));
363             this.$element.on('change',1)">this._changeElement = $.proxy(364                 365                 this.refresh(366             },1)">this))).on('focus',1)">this._focusElement = $.proxy(367                 368                 .open();
369             },1)">this))).on('blur',1)">this._blurElement = $.proxy(370                 .needBlur) {
371                     372                     373 374             },1)">)));
375             this.$textspan.on('click',1)">376                  $(e.target),type;
377                 $378                 if ($target.is('.select-item'379                     type = $target.data('count'380                     $.open(type);
381                 } 382                     if ($this.$dropdown.is(':visible'383                         $.close();
384                     } 385                         $386 387 388             }).on('mousedown',1)">389                 $390             });
391             this.$dropdown.on('click','.city-select a',1)">392                 var $select = $(this).parents('.city-select'393                 var $active = $select.find('a.active'394                 var last = $select.next().length === 0395                 $active.removeClass('active'396                 $(this).addClass('active'397                 if ($active.data('code') !== $(this).data('code'398                     $select.data('item'399                         address: $(this).attr('title'),code: $()
400                     });
401                     $().trigger(EVENT_CHANGE);
402                     $.feedText();
403                     $this.feedVal(404                      (last) {
405                         $406 407 408             }).on('click','.city-select-tab a',1)">409                 if (!$(this).hasClass('active'410                     var type = $(this).data('count'411                     $.tab(type);
412 413             }).on('mousedown',1)">414                 $415 416             .$province) {
417                 this.$province.on(EVENT_CHANGE,1)">this._changeProvince = $.proxy(418                     if(this.output(CITY)){判断下一个tab是否有数据,没有则关闭下拉
419                         $420                         421                     };
422                     this.output(CITY);
423                     this.output(DISTRICT);
424                     this.output(COUNTY);
425                     .tab(CITY);
426                 },1)">427 428             .$city) {
429                 this.$city.on(EVENT_CHANGE,1)">this._changeCity = $.proxy(430                     .output(DISTRICT)){
431                         $432                         433                     };
434                     .output(COUNTY);
435                     .tab(DISTRICT);
436                 },1)">437 438 
439             .$district) {
440                 this.$district.on(EVENT_CHANGE,1)">this._changeDistrict = $.proxy(441                     .output(COUNTY)){
442                         $443                         444 445                     .tab(COUNTY);
446                 },1)">447 448 449         显示下拉
450         open: 451             type = type || PROVINCE;
452             .$dropdown.show();
453             this.$textspan.addClass('open').addClass('focus'454             455 456         关闭下拉
457         close:  (blur) {
458             .$dropdown.hide();
459             this.$textspan.removeClass('open'460             461                 this.$textspan.removeClass('focus'462 463 464         解绑事件
465         unbind: 466 
467             $(document).off('click',1)">._mouteclick);
468 
469             this.$element.off('change',1)">._changeElement);
470             this.$element.off('focus',1)">._focusElement);
471             this.$element.off('blur',1)">._blurElement);
472 
473             this.$textspan.off('click'474             this.$textspan.off('mousedown'475 
476             this.$dropdown.off('click'477             this.$dropdown.off('mousedown'478 
479             480                 this.$province.off(EVENT_CHANGE,1)">._changeProvince);
481 482 
483             484                 this.$city.off(EVENT_CHANGE,1)">._changeCity);
485 486 
487             488                 this.$district.off(EVENT_CHANGE,1)">._changeDistrict);
489 490 491         获取选择项信息
492         getText: 493             var text = ''494             495                 .each(496                     var item = $(this).data('item'),1)">497                         type = $(498                      (item) {
499                         text += ($(this).hasClass('province') ? '' : '/') + '<span class="select-item" data-count="' +
500                             type + '" data-code="' + item.code + '">' + item.address + '</span>'501 502 503              text;
504 505         getPlaceHolder: 506             return .options.placeholder;
507 508         显示placeholder或者选择的区域
509         feedText: 510             var text = .getText();
511              (text) {
512                 this.$textspan.find('>.placeholder').hide();
513                 this.$textspan.find('>.title').html(.getText()).show();
514             } 515                 this.$textspan.find('>.placeholder').text(.getPlaceHolder()).show();
516                 this.$textspan.find('>.title').html(''517 518 519         getCode:  (count) {
520             var obj = {},arr =521             this.$textspan.find('.select-item'522                 .each(523                     var code = $(524                     var count = $(525                     obj[count] = code;
526                     arr.push(code);
527 528             return count ? obj[count] : arr.join('/'529 530         getVal: 531             532             var code=''533             534                 .each(535                     536                     537                         text += ($(this).hasClass('province') ? '' : '/') + item.address;
538                         code += ($(this).hasClass('province') ? '' : '_') + item.code;
539 540 541             $("#addrValue").val(code);
542             543 544         input的value赋值
545         feedVal:  (trigger) {
546             this.$element.val(.getVal());
547             (trigger) {
548                 this.$element.trigger('cp:updated'549 550 551         输出数据
552         output: 553             554             var options = .options;
555             var placeholders = this.placeholders;
556             this['$' + type];
557             var data = type === PROVINCE ? {} : [];
558              item;
559              districts;
560             561             var matched = 562              value;
563             if (!$select || !$select.length) {
564                 565 566             item = $select.data('item'567             value = (item ? item.address : null) || options[type];
568             code = (
569                 type === PROVINCE ? 86 :
570                     type === CITY ? this.$province && this.$province.find('.active').data('code') :
571                         type === DISTRICT ? this.$city && this.$city.find('.active').data('code'572                             type === COUNTY ? this.$district && this.$district.find('.active').data('code') : code
573             );
574             districts = $.isNumeric(code) ? ChineseDistricts[code] : null;
575        //判断是否应该去远程加载数据
576             districts = $.isNumeric(code) ? this.remoteLoadData(type,code) : null;
577              ($.isPlainObject(districts)) {
578                 $.each(districts,1)"> (code,address) {
579                      provs;
580                     if (type === PROVINCE) {
581                         provs =582                         for (var i = 0; i < address.length; i++583                             if (address[i].address === value) {
584                                 matched =585                                     code: address[i].code,1)">586                                     address: address[i].address
587                                 };
588                             }
589                             provs.push({
590                                 code: address[i].code,1)">591                                 address: address[i].address,1)">592                                 selected: address[i].address === value
593                             });
594                         }
595                         data[code] =596                     } 597                         if (address ===598                             matched =599                                 code: code,1)">600                                 address: address
601                             };
602 603                         data.push({
604                             code: code,1)">605                             address: address,1)">606                             selected: address ===607                         });
608 609 610 611 
612             $select.html(type === PROVINCE ? .getProvinceList(data) :
613                 .getList(data,type));
614             $select.data('item',matched);当前tab添加item(包含选择对象的内容)
615             if(! (type === PROVINCE)){标识:下一个选项没有数据则关闭
616                 if(data.length==0){
617                     618 619 620 621         遍历省份
622         getProvinceList:  (data) {
623             var list = [],1)">624                 $625                 simple = .options.simple;
626 
627             $.each(data,n) {
628                 list.push('<dl class="clearfix">'629                 list.push('<dt>' + i + '</dt><dd>'630                 $.each(n,1)"> (j,m) {
631                     list.push(
632                         '<a' +
633                         ' title="' + (m.address || '') + '"' +
634                         ' data-code="' + (m.code || '') + '"' +
635                         ' class="' +
636                         (m.selected ? ' active' : '') +
637                         '">' +
638                         ( simple ? $this.simplize(m.address,PROVINCE) : m.address) +
639                         '</a>'640 641                 list.push('</dd></dl>'642 643 
644             return list.join(''645 646         遍历市或区或县
647         getList:  (data,1)">648             649                 $650                 simple = 651             list.push('<dl class="clearfix"><dd>'652 
653             $.each(data,1)">654                 list.push(
655                     '<a' +
656                     ' title="' + (n.address || '') + '"' +
657                     ' data-code="' + (n.code || '') + '"' +
658                     ' class="' +
659                     (n.selected ? ' active' : '') +
660                     '">' +
661                     ( simple ? $this.simplize(n.address,type) : n.address) +
662                     '</a>'663 664             list.push('</dd></dl>'665 
666             667 668         简化名字
669         simplize:  (address,1)">670             address = address || ''671             672                 return address.replace(/[省,市,自治区,壮族,回族,维吾尔]/g,''673             }  CITY) {
674                 return address.replace(/[市,地区,蒙古,苗族,白族,傣族,景颇族,藏族,彝族,傈僳族,布依族,侗族]/g,1)">675                     .replace('哈萨克','').replace('自治州','').replace(/自治县/,1)">676             }  DISTRICT) {
677                 return address.length > 2 ? address.replace(/[市,区,县,旗]/g,1)">) : address;
678 679 680         处理tab显示
681         tab: 682             var $selects = 683             var $tabs = this.$dropdown.find('.city-select-tab > a'684             685             var $tab = this.$dropdown.find('.city-select-tab > a[data-count="' + type + '"]'686              ($select) {
687                 $selects.hide();
688                 $select.show();
689                 $tabs.removeClass('active'690                 $tab.addClass('active'691 692 693 
694         reset: 695             null).trigger('change'696 697 
698         destroy: 699             .unbind();
700             this.$element.removeData(NAMESPACE).removeClass('city-picker-input'701             .$textspan.remove();
702             .$dropdown.remove();
703 704         远程加载数据
705         remoteLoadData: function (cityType,cityId) {
706             var resultData = {};
707             if(PROVINCE===cityType)
708             {
709                 return ChineseDistricts[cityId];
710             }
711             $.ajax({
712                 url: "/directoryProcurement/jd/cityData/"+cityType+"/"+cityId,713                 type: "GET",714                 dataType: "json",715                 async: false,716                 contentType: "application/json",717                 success: function (result) {
718                     if(result.code=="0")
719                     {
720                         resultData = result.data;
721                     }else
722                     {
723                         console.log(result.desc);
724                     }
725                 }
726             });
727             return resultData;
728         }
729     };
730 
731     CityPicker.DEFAULTS =732         simple: 733         responsive: 734         placeholder: '请选择省/市/区/镇'735         level: 'county'736         province: ''737         city: ''738         district: ''739         county:''
740 741 
742     CityPicker.setDefaults =  (options) {
743         $.extend(CityPicker.DEFAULTS,options);
744 745 
746      Save the other citypicker
747     CityPicker.other = $.fn.citypicker;
748 
749      Register as jQuery plugin
750     $.fn.citypicker =  (option) {
751         var args = [].slice.call(arguments,1752 
753         this.each(754             this = $(755             var data = $.data(NAMESPACE);
756              options;
757              fn;
758 
759             data) {
760                 if (/destroy/.test(option)) {
761                     762 763 
764                 options = $.extend({},$this.data(),$.isPlainObject(option) && option);
765                 $this.data(NAMESPACE,(data = new CityPicker(766 767 
768             typeof option === 'string' && $.isFunction(fn = data[option])) {
769                 fn.apply(data,args);
770 771         });
772 773 
774     $.fn.citypicker.Constructor = CityPicker;
775     $.fn.citypicker.setDefaults = CityPicker.setDefaults;
776 
777      No conflict
778     $.fn.citypicker.noConflict = 779         $.fn.citypicker = CityPicker.other;
780         781 782 
783     $(784         $('[data-toggle="city-picker"]').citypicker();
785     });
786 });

上面的代码的第一个红色字体处,是为将省和直辖市这种一级地址默认加载过来,其他的三级地址都是靠远程加载过来,

第二处红色字体是为了解决,上面是为了解决一个bug,就当选择了,一级二级三级和四级地址后,如果再重新选择一级地址,后面的三级地址不会清空重选,这样会造成地址归属地不对的问题,这个bug在city-picker原生的代码中是没有的,应该是上面那个博客里,改成四级地址后才出现的bug。

第三处红色字体是为了判断是否有应该去进行远程加载数据,如果只选择了一级地址,就不去远程加载数据,反之则调用远程加载数据方法。

第四处红色字体,是关键了,实现远程加载数据的方法,这个方法是我自己后来加的,写成了同步请求。因为有些地址就没有三级地址,例如北京、丰台、三环到四环之间、这就是一个完整的选择地址了,所以会把一些没有四级地址的信息打印出来,如果有需要的可以修改这个远程加载数据的方法,来实现自己的需求。

最后忘记说了,我是将city-picker.js这个插件的city-picker.data.js和city-picker.js这两个文件合并成了一个文件,因为我只需要默认加载一级地址,一级地址的内容也不多,就写在了一起了,就是第一处红色字体处的js全局对象。

粗略的改造,接受批评。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读