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

Posted 纪莫

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了四级地址插件升级改造(京东商城地址选择插件)city-picker相关的知识,希望对你有一定的参考价值。

最近公司做的项目要和京东的数据做对接,所以要做个类似京东商品的详情页。页面的数据,是可以从京东接口获取到的,但是地址插件选择的效果需要自己实现。前端的同事在之前的项目中,已经选择了一款地址插件(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 if (typeof exports === \'object\') {
160         // Node / CommonJS
161         factory(require(\'jquery\'), require(\'ChineseDistricts\'));
162     } else {
163         // Browser globals.
164         factory(jQuery, ChineseDistricts);
165     }
166 })(function ($, ChineseDistricts) {
167 
168     \'use strict\';
169     if (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     function CityPicker(element, options) {
180         this.$element = $(element);
181         this.$dropdown = null;
182         this.options = $.extend({}, CityPicker.DEFAULTS, $.isPlainObject(options) && options);
183         this.active = false;
184         this.dems = [];
185         this.needBlur = false;
186         this.init();
187     }
188 
189     CityPicker.prototype = {
190         constructor: CityPicker,
191 
192         init: function () {
193 
194             this.defineDems();
195 
196             this.render();
197 
198             this.bind();
199 
200             this.active = true;
201         },
202         //界面显示处理
203         render: function () {
204             var p = this.getPosition(),
205                 placeholder = this.$element.attr(\'placeholder\') || this.options.placeholder,
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>\',
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(this.$element);
230             this.$dropdown = $(dropdown).insertAfter(this.$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(function (i, type) {
235                 this[\'$\' + type] = $select.filter(\'.\' + type + \'\');
236             }, this));
237 
238             this.refresh();
239         },
240 
241         refresh: function (force) {
242             // clean the data-item for each $select
243             var $select = this.$dropdown.find(\'.city-select\');
244             $select.data(\'item\', null);
245             // parse value from value of the target $element
246             var val = this.$element.val() || \'\';
247             val = val.split(\'/\');
248             $.each(this.dems, $.proxy(function (i, type) {//遍历dems
249                 if (val[i] && i < val.length) {
250                     this.options[type] = val[i];//把当前显示值赋值给options
251                 } else if (force) {
252                     this.options[type] = \'\';
253                 }
254                 this.output(type);//输出下拉框显示数据
255             }, this));
256             this.tab(PROVINCE);
257             this.feedText();//界面显示选择的内容
258             this.feedVal();//input标签value赋值
259         },
260         //dems赋值
261         defineDems: function () {
262             var stop = false;
263             $.each([PROVINCE, CITY, DISTRICT,COUNTY], $.proxy(function (i, type) {
264                 if (!stop) {
265                     this.dems.push(type);
266                 }
267                 if (type === this.options.level) {
268                     stop = true;
269                 }
270             }, this));
271         },
272 
273         includeDem: function (type) {
274             return $.inArray(type, this.dems) !== -1;
275         },
276 
277         getPosition: function () {
278             var p, h, w, s, pw;
279             p = this.$element.position();
280             s = this.getSize(this.$element);
281             h = s.height;
282             w = s.width;
283             if (this.options.responsive) {
284                 pw = this.$element.offsetParent().width();
285                 if (pw) {
286                     w = w / pw;
287                     if (w > 0.99) {
288                         w = 1;
289                     }
290                     w = w * 100 + \'%\';
291                 }
292             }
293 
294             return {
295                 top: p.top || 0,
296                 left: p.left || 0,
297                 height: h,
298                 width: w
299             };
300         },
301 
302         getSize: function ($dom) {
303             var $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(),
316                     height: $clone.outerHeight()
317                 };
318 
319                 $wrap.remove();
320             } else {
321                 sizes = {
322                     width: $dom.outerWidth(),
323                     height: $dom.outerHeight()
324                 };
325             }
326 
327             return sizes;
328         },
329 
330         getWidthStyle: function (w, dropdown) {
331             if (this.options.responsive && !$.isNumeric(w)) {
332                 return \'width:\' + w + \';\';
333             } else {
334                 return \'width:\' + (dropdown ? Math.max(320, w) : w) + \'px;\';
335             }
336         },
337         //绑定事件
338         bind: function () {
339             var $this = this;
340             $(document).on(\'click\', (this._mouteclick = function (e) {
341                 var $target = $(e.target);
342                 var $dropdown, $span, $input;
343                 if ($target.is(\'.city-picker-span\')) {
344                     $span = $target;
345                 } else if ($target.is(\'.city-picker-span *\')) {
346                     $span = $target.parents(\'.city-picker-span\');
347                 }
348                 if ($target.is(\'.city-picker-input\')) {
349                     $input = $target;
350                 }
351                 if ($target.is(\'.city-picker-dropdown\')) {
352                     $dropdown = $target;
353                 } else 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(true);
361                 }
362             }));
363             this.$element.on(\'change\', (this._changeElement = $.proxy(function () {
364                 this.close(true);
365                 this.refresh(true);
366             }, this))).on(\'focus\', (this._focusElement = $.proxy(function () {
367                 this.needBlur = true;
368                 this.open();
369             }, this))).on(\'blur\', (this._blurElement = $.proxy(function () {
370                 if (this.needBlur) {
371                     this.needBlur = false;
372                     this.close(true);
373                 }
374             }, this)));
375             this.$textspan.on(\'click\', function (e) {
376                 var $target = $(e.target), type;
377                 $this.needBlur = false;
378                 if ($target.is(\'.select-item\')) {
379                     type = $target.data(\'count\');
380                     $this.open(type);
381                 } else {
382                     if ($this.$dropdown.is(\':visible\')) {
383                         $this.close();
384                     } else {
385                         $this.open();
386                     }
387                 }
388             }).on(\'mousedown\', function () {
389                 $this.needBlur = false;
390             });
391             this.$dropdown.on(\'click\', \'.city-select a\', function () {
392                 var $select = $(this).parents(\'.city-select\');
393                 var $active = $select.find(\'a.active\');
394                 var last = $select.next().length === 0;
395                 $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: $(this).data(\'code\')
400                     });
401                     $(this).trigger(EVENT_CHANGE);
402                     $this.feedText();
403                     $this.feedVal(true);
404                     if (last) {
405                         $this.close();
406                     }
407                 }
408             }).on(\'click\', \'.city-select-tab a\', function () {
409                 if (!$(this).hasClass(\'active\')) {
410                     var type = $(this).data(\'count\');
411                     $this.tab(type);
412                 }
413             }).on(\'mousedown\', function () {
414                 $this.needBlur = false;
415             });
416             if (this.$province) {
417                 this.$province.on(EVENT_CHANGE, (this._changeProvince = $.proxy(function () {
418                     if(this.output(CITY)){//判断下一个tab是否有数据,没有则关闭下拉
419                         $this.close();
420                         return;
421                     };
422                     this.output(CITY);
423                     this.output(DISTRICT);
424                     this.output(COUNTY);
425                     this.tab(CITY);
426                 }, this)));
427             }
428             if (this.$city) {
429                 this.$city.on(EVENT_CHANGE, (this._changeCity = $.proxy(function () {
430                     if(this.output(DISTRICT)){
431                         $this.close();
432                         return;
433                     };
434                     this.output(COUNTY);
435                     this.tab(DISTRICT);
436                 }, this)));
437             }
438 
439             if (this.$district) {
440                 this.$district.on(EVENT_CHANGE, (this._changeDistrict = $.proxy(function () {
441                     if(this.output(COUNTY)){
442                         $this.close();
443                         return;
444                     };
445                     this.tab(COUNTY);
446                 }, this)));
447             }
448         },
449         //显示下拉
450         open: function (type) {
451             type = type || PROVINCE;
452             this.$dropdown.show();
453             this.$textspan.addClass(\'open\').addClass(\'focus\');
454             this.tab(type);
455         },
456         //关闭下拉
457         close: function (blur) {
458             this.$dropdown.hide();
459             this.$textspan.removeClass(\'open\');
460             if (blur) {
461                 this.$textspan.removeClass(\'focus\');
462             }
463         },
464         //解绑事件
465         unbind: function () {
466 
467             $(document).off(\'click\', this._mouteclick);
468 
469             this.$element.off(\'change\', this._changeElement);
470             this.$element.off(\'focus\', this._focusElement);
471             this.$element.off(\'blur\', this._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             if (this.$province) {
480                 this.$province.off(EVENT_CHANGE, this._changeProvince);
481             }
482 
483             if (this.$city) {
484                 this.$city.off(EVENT_CHANGE, this._changeCity);
485             }
486 
487             if (this.$district) {
488                 this.$district.off(EVENT_CHANGE, this._changeDistrict);
489             }
490         },
491         //获取选择项信息
492         getText: function () {
493             var text = \'\';
494             this.$dropdown.find(\'.city-select\')
495                 .each(function () {
496                     var item = $(this).data(\'item\'),
497                         type = $(this).data(\'count\');
498                     if (item) {
499                         text += ($(this).hasClass(\'province\') ? \'\' : \'/\') + \'<span class="select-item" data-count="\' +
ecshop二次开发功能插件计划列表

jQuery插件jRange滑动选取数值范围---使用心得

分享一些经典的特效效果,希望对大家有帮助

分享一些经典的特效效果,希望对大家有帮助

使用jquery.cityselect插件选择省,市,区联动

028-Kodi中文插件库Gitee镜像地址