PageSourceSearch

https://www.svbony.jp/assets/js/global.js?v=1.4

js svbony.jp collected 2026-10-05 03:58:47 UTC 51,206 bytes, 1,444 lines download raw bytes

1
2
3var global_obj={
4	timer:'',
5	check_form:function(notnull_obj, format_obj, type, is_new){
6		var flag = false,
7			is_new = (typeof(arguments[3]) == 'undefined') ? 0 : 1,
8            errorObj = new Object;
9		if (notnull_obj) {
10			notnull_obj.not(':disabled').each(function(){
11				var $lang = $(this).parents('.tab_txt').attr('lang'); //后台语言版
12                if (!errorObj[$lang]) {
13                    errorObj[$lang] = 0;
14                }
15				if (!$(this).find('input').length && $.trim($(this).val()) == '') {
16					if ($lang) {
17                        //后台语言版
18                        errorObj[$lang] += 1;
19						$(this).parents('.rows').find('.tab_box_btn[data-lang='+$lang+']').addClass('empty');
20						$('.r_con_wrap').animate({scrollTop:$(this).parents('.rows').position().top}, 0);
21					}
22					if ($(this).attr('parent_null')) {
23                        //提示在父级
24						// $(this).parent().css('border', '1px solid red').addClass('null');
25						$(this).parents('[parent_null]').css('border', '1px solid red').addClass('null');
26					} else {
27						$(this).css('border', '1px solid red').addClass('null');
28					}
29					flag == false && ($(this).focus());
30					flag = true;
31				} else {
32					if (errorObj[$lang] == 0) {
33                        $(this).parents('.rows').find('.tab_box_btn[data-lang='+$lang+']').removeClass('empty');
34                    }
35					if ($(this).attr('parent_null')) {
36                        //提示在父级
37						$(this).parents('[parent_null]').removeAttr('style').removeClass('null');
38					} else {
39						$(this).removeAttr('style').removeClass('null');
40					}
41				}
42			});
43			//后台语言版
44			$('.rows').find('.tab_box_row .tips').hide();
45			$('.rows').find('.tab_box_row .tab_box_btn').each(function(){
46				if ($(this).hasClass('empty')) {
47					$(this).parents('.tab_box_row').find('.tips').show();
48				}
49			});
50			if (flag){ return flag; };
51		}
52		if(format_obj){
53			var reg={
54				'MobilePhone':/^1[3456789]\d{9}$/,
55				'Telephone':/^(0\d{2,3})(-)?(\d{7,8})(-)?(\d{3,})?$/,
56				'Fax':/^(0\d{2,3})(-)?(\d{7,8})(-)?(\d{3,})?$/,
57				'Email':/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/,
58				'Length':/^.*/
59			};
60			var tips={
61				'MobilePhone':lang_obj.format.mobilephone,
62				'Telephone':lang_obj.format.telephone,
63				'Fax':lang_obj.format.fax,
64				'Email':lang_obj.format.email,
65				'Length':lang_obj.format.length
66			};
67			if(type==1){
68				format_obj.each(function(){
69					var o=$(this);
70					if($.trim(o.val())){
71						if(reg[o.attr('format')].test($.trim(o.val()))===false){
72							o.css('border', '1px solid red').addClass('null');
73							o.focus();
74							flag=true;
75						}
76					}
77				});
78			}else{
79				format_obj.each(function(){
80					var o=$(this);
81					var s=o.attr('format').split('|');
82					if(!$.trim(o.val())){
83						flag=false;
84					}else if((s[0]=='Length' && $.trim(o.val()).length!=parseInt(s[1])) || (s[0]!='Length' && reg[s[0]].test($.trim(o.val()))===false)){
85						if(is_new==1){
86							global_obj.new_win_alert(tips[s[0]].replace('%num%', s[1]));
87						}else{
88							global_obj.win_alert(tips[s[0]].replace('%num%', s[1]));
89						}
90						o.css('border', '1px solid red').addClass('null');
91						o.focus();
92						flag=true;
93						return false;
94					}
95				});
96			}
97		}
98		return flag;
99	},
100
101	win_alert:function(tips, callback, type, is_pop, status){
102		type = (typeof(arguments[2]) == 'undefined') ? 'alert' : arguments[2]
103		is_pop = (typeof(arguments[3]) == 'undefined') ? 0 : 1
104		status = (typeof(arguments[4]) == 'undefined') ? '' : arguments[4] //status => success(成功) fail(失败)
105		let false_callback = (typeof(arguments[5]) == 'undefined') ? '' : arguments[5] //false_callback 取消后的回调函数
106		let not_remove_mask = $('.not_remove_mask:visible').length ? 1 : 0	//不删除遮罩层
107		let html
108		let title = tips
109		let subtitle = ''
110		let confirmBtn = lang_obj.web.global.confirm
111		let cancelBtn = lang_obj.web.global.cancel
112		let confirmBtnClass = ''
113		let winBtnsClass = ''
114		let extHtml = ''
115		let alertClass = ''
116		if (typeof(tips) == 'object') {
117			title = tips.title
118			subtitle = tips.subtitle
119			if (tips.confirmBtn) confirmBtn = tips.confirmBtn
120			if (tips.cancelBtn) cancelBtn = tips.cancelBtn
121			if (tips.confirmBtnClass) confirmBtnClass = tips.confirmBtnClass
122			if (tips.extHtml) extHtml = tips.extHtml
123			if (tips.winBtnsClass) winBtnsClass = tips.winBtnsClass
124			if (tips.alertClass) alertClass = tips.alertClass
125		}
126		$('#div_mask, .win_alert').remove();//优先清空多余的弹出框
127		global_obj.div_mask();
128		html='<div class="win_alert ' + alertClass + '">';
129			html+='<div class="win_close"><button class="close">x</button></div>';
130			html+='<div class="win_content">';
131				if (status) html+='<div class="win_status ' + status + '"></div>';
132				html+='<div class="win_title">' + title + '</div>';
133				if (subtitle) html+='<div class="win_tips">' + subtitle + '</div>';
134				if (extHtml) html+='<div class="ext_html">' + extHtml + '</div>';
135				html+='<div class="win_btns ' + winBtnsClass + '">';
136					if(type=='confirm'){
137						html+='<button class="btn btn_sure ' + confirmBtnClass + '">' + confirmBtn + '</button>';
138						html+='<button class="btn btn_cancel">' + cancelBtn + '</button>';
139					}else{
140						html+='<button class="btn btn_sure ' + confirmBtnClass + ' btn_once_sure">' + confirmBtn + '</button>';
141					}
142				html+='</div>';
143			html+='</div>'
144		html+='</div>';
145		$('body').prepend(html);
146		$('.win_alert').css({left:$(window).width()/2-$('.win_alert').outerWidth(true)/2,top:'30%'});
147		if(type=='confirm'){
148			$('.win_alert').delegate('.close, .btn_cancel', 'click', function(){
149				$('.win_alert').remove();
150				is_pop==0 && not_remove_mask==0 && global_obj.div_mask(1);
151				$.isFunction(false_callback) && false_callback();
152			}).delegate('.btn_sure', 'click', function(){
153				let result = true
154				$.isFunction(callback) && (result = callback())
155				if (result === false) return false
156				$('.win_alert').remove();
157				is_pop==0 && not_remove_mask==0 && global_obj.div_mask(1);
158			});
159		}else{
160			$('.win_alert').delegate('.close, .btn_sure', 'click', function(){
161				let result = true
162				$.isFunction(callback) && (result = callback())
163				if (result === false) return false;
164				$('.win_alert').remove();
165				is_pop==0 && not_remove_mask==0 && global_obj.div_mask(1);
166			});
167		}
168		return false;
169	},
170
171	/**
172	 * 弹窗载入进度
173	 */
174	win_loading:function()
175	{
176		$('#div_mask, .win_alert').remove();//优先清空多余的弹出框
177		global_obj.div_mask();
178		html='<div class="win_alert">';
179			html+='<div class="win_close"><button class="close">x</button></div>';
180			html+='<div class="win_content">';
181				html+='<div id="box_circle_container">';
182					html+='<div class="box_circle_progress" data-percent="0" data-animate="0">';
183						html+='<div class="wrapper circle_progress_right">';
184							html+='<div class="circle_progress rightcircle"></div>';
185						html+='</div>';
186						html+='<div class="wrapper circle_progress_left">';
187							html+='<div class="circle_progress leftcircle"></div>';
188						html+='</div>';
189						html+='<div class="circle_progress_number"><span>0</span>%</div>';
190						html+='<div class="circle_progress_completed"></div>';
191					html+='</div>';
192					html+='<div class="circle_progress_text"></div>';
193				html+='</div>';
194			html+='</div>'
195		html+='</div>';
196		$('body').prepend(html);
197		$('.win_alert').css({left:$(window).width()/2-$('.win_alert').outerWidth(true)/2,top:'30%'});
198		$('.win_alert').delegate('.close, .btn_sure', 'click', function(){
199			$('.win_alert').remove();
200			global_obj.div_mask(1);
201		});
202		return false;
203	},
204
205	new_win_alert:function(tips, callback, type, is_pop, status, btn){ //status => await(叹号) fail(红叉)
206		var type=(typeof(arguments[2])=='undefined')?'alert':arguments[2],
207			is_pop=(typeof(arguments[3])=='undefined')?0:1,
208			status=(typeof(arguments[4])=='undefined')?'await':arguments[4],
209			btn=(typeof(arguments[5])=='undefined')?lang_obj.web.global.confirm:arguments[5],
210			html;
211		$('#div_mask, .new_win_alert').remove();//优先清空多余的弹出框
212		global_obj.div_mask();
213		html='<div class="new_win_alert themes_popups">';
214			html+='<div class="win_close"><button class="close"></button></div>';
215			html+='<div class="win_tips"><i class="icon_success_status '+status+'"></i>'+tips+'</div>';
216			html+='<div class="win_btns">';
217				if(type=='confirm') html+='<button class="btn btn_cancel">'+lang_obj.web.global.cancel+'</button>';
218				html+='<button class="btn btn_sure">'+btn+'</button>';
219			html+='<div class="clear"></div>';
220			html+='</div>';
221		html+='</div>';
222		$('body').prepend(html);
223		$('.new_win_alert').css({left:$(window).width()/2-$('.new_win_alert').outerWidth()/2, top:'30%'});
224		if(type=='confirm'){
225			$('.new_win_alert').delegate('.close, .btn_cancel', 'click', function(){
226				$('.new_win_alert').remove();
227				is_pop==0 && global_obj.div_mask(1);
228			}).delegate('.btn_sure', 'click', function(){
229				$.isFunction(callback) && callback();
230				$('.new_win_alert .close').click();
231			});
232		}else{
233			$('.new_win_alert').delegate('.close, .btn_sure', 'click', function(){
234				$.isFunction(callback) && callback();
235				$('.new_win_alert').remove();
236				is_pop==0 && global_obj.div_mask(1);
237			});
238		}
239		return false;
240	},
241
242	/*
243	 *	@param:	tips			提示内容
244	 *	@param:	status			类型,留空(打钩) await(叹号) fail(红叉) loading(加载中)
245	 *	@param:	time			停留时间 (-1: 针对loading效果固定显示)
246	 *	@param:	pos_top			与顶部的距离
247	 *	@param:	no_remove_mask	是否优先清除多余的弹出框
248	 */
249	win_alert_auto_close:function(tips, status, time, pos_top, no_remove_mask){
250		var status=(typeof(arguments[1])=='undefined')?'await':arguments[1],
251			time=(typeof(arguments[2])=='undefined' || !arguments[2])?'2000':arguments[2],
252			pos_top=(typeof(arguments[3])=='undefined' || !arguments[3])?'40%':arguments[3],
253			no_remove_mask=(typeof(arguments[4])=='undefined')?1:arguments[4],
254			html='';
255		if(no_remove_mask) $('#div_mask, .new_win_alert').remove();//优先清空多余的弹出框
256		if(status!='loading' || (status=='loading' && time==-1)){
257			//除了loading Or 固定显示loading
258			html+='<div class="new_win_alert win_alert_auto_close'+(status=='loading'?' win_alert_loading':'')+'">';
259			html+=	'<div class="win_tips"><i class="icon_success_status '+status+'"></i>'+tips+'</div>';
260			html+='</div>';
261			$('body').prepend(html);
262			$('.new_win_alert').css({left:$(window).width()/2-$('.new_win_alert').outerWidth(true)/2, top:pos_to
262p});
263		}
264		clearTimeout(global_obj.timer);
265		if(status!='loading' || (status=='loading' && time>=0)){
266			//除了loading Or 计时自动关闭loading
267			global_obj.timer=setTimeout(function(){
268				$('.new_win_alert').remove();
269			}, time);
270		}
271		return false;
272	},
273
274	div_mask:function(remove){
275		var obj=(typeof(arguments[1])=='undefined')?'':arguments[1],
276			$obj = $('body');
277			if (typeof(obj) == 'object') $obj = obj;
278		if(remove==1){
279			$('#div_mask').remove();
280		}else{
281			if(!$('#div_mask').length){
282				$obj.prepend('<div id="div_mask"></div>');
283				$('#div_mask').css({width:'100%', height:$(document).height(), overflow:'hidden', position:'fixed', top:0, left:0, background:'#000', opacity:0.6, 'z-index':10000});
284			}
285		}
286	},
287
288	data_posting:function(display, tips){
289		if(display){
290			$('body').prepend('<div id="data_posting"><img src="' + shop_config.CDN_URL + 'ico/data_posting.gif" style="margin-top: 4px;display: inline-block;vertical-align: top;" width="16" height="16" align="absmiddle" />&nbsp;&nbsp;'+tips+'</div>');
291			$('#data_posting').css({
292				width:'188px',
293				height:'24px',
294				'line-height':'24px',
295				padding:'0 8px',
296				overflow:'hidden',
297				border:'1px solid #bbb',
298				background:'#ddd',
299				position:'fixed',
300				top:'40%',
301				left:'0',
302				right:'0',
303				margin:'auto',
304				'z-index':10001
305			});
306		}else{
307			setTimeout('$("#data_posting").remove();', 500);
308		}
309	},
310
311	urlencode:function(str) {
312		str = (str + '').toString();
313		return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/\*/g, '%2A').replace(/%20/g, '+');
314	},
315
316	json_encode_data:function(value){
317		var result=new Object();
318		if(typeof(value)=='string' && value){
319			if(typeof(JSON)=='object'){
320				result=JSON.parse(value);
321			}else{
322				var ary, arr, key;
323				ary=value.substr(1,value.length-2).split(',"');//踢走{}
324				for(var i=0; i<ary.length; i++){
325					arr=ary[i].split(':');
326					key=parseInt(isNaN(arr[0]) ? (i==0?arr[0].substr(1,arr[0].length-2):arr[0].substr(0,arr[0].length-1)): arr[0]);//确保键是数字
327					if(arr[1].substr(0,1)=='['){//值为数组
328						result[key]=arr[1].substr(1,arr[1].length-2).split(',');
329					}else{
330						result[key]=arr[1];
331					}
332				}
333			}
334		}else{
335			result=value;
336		}
337		return result;
338	},
339
340	json_decode_data:function(value){
341		var result;
342		if(typeof(value)=='object'){
343			if(typeof(JSON)=='object'){
344				result=JSON.stringify(value);
345			}else{
346				result='';
347				for(k in value){
348					if(global_obj.is_array(value[k])){
349						result+=('"'+k+'":['+value[k]+'],');
350					}else{
351						result+=('"'+k+'":"'+value[k]+'",');
352					}
353				}
354				result='{'+result.substr(0,result.length-1)+'}';
355			}
356		}else{
357			result=value;
358		}
359		return result;
360	},
361
362	in_array:function(needle, arr){
363		for(var i=0; i<arr.length && arr[i]!=needle; i++);
364		return !(i==arr.length);
365	},
366
367	is_array:function(data){
368		if(Object.prototype.toString.call(data)=='[object Array]'){
369			return true;
370		}else{
371			return false;
372		}
373	},
374
375	base64_encode:function(str){
376		var c1, c2, c3;
377		var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
378		var i = 0, len= str.length, string = '';
379		while (i < len){
380			c1 = str.charCodeAt(i++) & 0xff;
381			if (i == len){
382				string += base64EncodeChars.charAt(c1 >> 2);
383				string += base64EncodeChars.charAt((c1 & 0x3) << 4);
384				string += "==";
385				break;
386			}
387			c2 = str.charCodeAt(i++);
388			if (i == len){
389				string += base64EncodeChars.charAt(c1 >> 2);
390				string += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
391				string += base64EncodeChars.charAt((c2 & 0xF) << 2);
392				string += "=";
393				break;
394			}
395			c3 = str.charCodeAt(i++);
396			string += base64EncodeChars.charAt(c1 >> 2);
397			string += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
398			string += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6));
399			string += base64EncodeChars.charAt(c3 & 0x3F)
400		}
401		return string
402	},
403
404	htmlspecialchars:function(str){
405		str = str.replace(/&/g, '&amp;');
406		str = str.replace(/</g, '&lt;');
407		str = str.replace(/>/g, '&gt;');
408		str = str.replace(/"/g, '&quot;');
409		str = str.replace(/'/g, '&#039;');
410		return str;
411	},
412
413	htmlspecialchars_decode:function(str){
414		str = str.replace(/&amp;/g, '&');
415		str = str.replace(/&lt;/g, '<');
416		str = str.replace(/&gt;/g, '>');
417		str = str.replace(/&quot;/g, '"');
418		str = str.replace(/&#039;/g, "'");
419		str = str.replace(/&#39;/g, "'");
420		return str;
421    },
422
423	n2br:function (str) {
424		var i;
425		var result = "";
426		var c;
427		for (i = 0; i < str.length; i++) {
428			c = str.substr(i, 1);
429			if ( c == "\n")
430				result = result + "</br>";
431			else if (c != "\r")
432				result = result + c;
433		}
434
435		return result;
436	},
437
438	attr_htmlspecialchars:function(str){
439		str = str.replace(/&/g, '&amp;');
440		str = str.replace(/</g, '&lt;');
441		str = str.replace(/>/g, '&gt;');
442		str = str.replace(/"/g, '&quot;');
443		return str;
444	},
445
446	web_attr_htmlspecialchars:function(str){
447		str = str.replace(/&/g, '&amp;');
448		str = str.replace(/</g, '&lt;');
449		str = str.replace(/>/g, '&gt;');
450		return str;
451	},
452
453	setCookie:function(name, value, expiredays){
454		var exdate=new Date();
455		exdate.setDate(exdate.getDate()+expiredays);
456		document.cookie=name+"="+escape(value)+((expiredays==null) ? "" : ";expires="+exdate.toGMTString());
457	},
458
459	getCookie:function(name){
460		if(document.cookie.length>0){
461			start=document.cookie.indexOf(name+"=");
462			if(start!=-1){
463				start=start+(name.length+1);
464				end=document.cookie.indexOf(";", start);
465				if(end==-1) end=document.cookie.length;
466				return unescape(document.cookie.substring(start, end));
467			}
468		}
469		return "";
470	},
471
472	delCookie:function(name, expiredays){
473		var exdate=new Date();
474		exdate.setDate(exdate.getDate()-1);
475		var value=global_obj.getCookie(name)
476		if(value){
477			document.cookie=name+"="+escape(value)+((expiredays==null) ? "" : ";expires="+exdate.toGMTString());
478		}
479	},
480
481	Waterfall:function(container, colWidth, colCount, cls){
482		function Waterfall(param){
483		    this.id = typeof param.container == 'string' ? document.getElementById(param.container) : param.container;
484		    this.colWidth = param.colWidth;
485		    this.colCount = param.colCount || 4;
486		    this.cls = param.cls && param.cls != '' ? param.cls : 'wf-cld';
487		    this.init();
488		}
489		//瀑布流
490		Waterfall.prototype = {
491		    getByClass:function(cls,p){
492		        var arr = [],reg = new RegExp("(^|\\s+)" + cls + "(\\s+|$)","g");
493		        var nodes = p.getElementsByTagName("*"),len = nodes.length;
494		        for(var i = 0; i < len; i++){
495		            if(reg.test(nodes[i].className)){
496		                arr.push(nodes[i]);//
497		                reg.lastIndex = 0;
498		            }
499		        }
500		        return arr;
501		    },
502		    maxArr:function(arr){
503		        var len = arr.length,temp = arr[0];
504		        for(var ii= 1; ii < len; ii++){
505		            if(temp < arr[ii]){
506		                temp = arr[ii];
507		            }
508		        }
509		        return temp;
510		    },
511		    getMar:function(node){
512		        var dis = 0;
513		        if(node.currentStyle){
514		            dis = parseInt(node.currentStyle.marginBottom);
515		        }else if(document.defaultView){
516		            dis = parseInt(document.defaultView.getComputedStyle(node,null).marginBottom);
517		        }
518		        return dis;
519		    },
520		    getMinCol:function(arr){
521		        var ca = arr,cl = ca.length,temp = ca[0],minc = 0;
522		        for(var ci = 0; ci < cl; ci++){
523		            if(temp > ca[ci]){
524		                temp = ca[ci];
525		                minc = ci;
526		            }
527		        }
528		        return minc;
529		    },
530		    init:function(){
531		        var _this = this;
532		        var col = [],//列高
533		            iArr = [];//索引
534		        var nodes = _this.getByClass(_this.cls,_this.id),len = nodes.length;
535		        for(var i = 0; i < _this.colCount; i++){
536		            col[i] = 0;
537		        }
538		        for(var i = 0; i < len; i++){
539		            nodes[i].h = nodes[i].offsetHeight + _this.getMar(nodes[i]);
540		            iArr[i] = i;
541		        }
542
543		        for(var i = 0; i < len; i++){
544		            var ming = _this.getMinCol(col);
545		            nodes[i].style.left = ming * _this.colWidth + "px";
546		            nodes[i].style.top = col[ming] + "px";
547		            col[ming] += nodes[i].h;
548		        }
549
550		        _this.id.style.height = _this.maxArr(col) + "px";
551		    }
552		};
553
554		new Waterfall({
555		    "container": container, //id
556		    "colWidth": colWidth,
557		    "colCount": colCount,//parseInt($('#themes_box').width()/220)
558		    "cls": cls //class
559		});
560
561	},
562
563	sort:function(a,b){ //属性键值排序 Ov: 是海外仓 要排到最后
564		if(a.indexOf('Ov:')!=-1){
565			a=99999999;
566		}
567		if(b.indexOf('Ov:')!=-1){
568			b=99999999;
569		}
570		return a - b;
571	},
572
573	checkCharLength:function(box,content){ //字长判断
574		var e=$(box);
575		e.change(function(event){
576			var curLength=e.val().length;
577			var maxlength=e.attr('maxlength');
578			if(curLength>maxlength){
579				e.val($.trim(e.val()).substr(0, maxlength - 1)).trigger('change');
580				return;
581			}
582			$('#review_form .font_tips em').text(curLength);
583			$(content).text(maxlength-curLength).parent().toggleClass('red', curLength>maxlength);
584		}).keyup(function(){
585			e.trigger('change');
586		});
587	},
588
589	 checkAddressFormat: function (t = 0, e = "", i = "", s = []) { if (value = $.trim(i), taxCodeTypeName = s.taxCodeTypeName, countryName = s.countryName, 30 == t) if (1 == e) var n = /^\d{3}\.\d{3}\.\d{3}-\d{2}$/; else { if (2 != e) return !1; n = /^\d{2}\.\d{3}\.\d{3}\/\d{4}-\d{2}$/ } else if (43 == t) { if (5 == e) n = /^\d{2}\.\d{3}\.\d{3}-[0-9Kk]$/ } else { if (211 != t) return !1; if (3 == e || 4 == e) n = /^\d{13}$/ } return !("object" != typeof Countries[t].field || !Countries[t].field) && ("" == i ? lang_obj.user.account.address_tips_PleaseEnter.replace("{Field}", taxCodeTypeName) : 0 == n.test(value) && lang_obj.checkout.checkout.errorTaxCodeFormat.replace("{TaxCodeName}", taxCodeTypeName).replace("{CountryName}", countryName)) },
590
591	/**
592	 *  获取当前地址url的get参数
593	 *  @param value[string] 需要获取get的参数
594	 *  @param selecter[string]  选择器,一般不需要,有些在iframe里面的,这里就写parent
595	 *  @param url[string]  链接get参数 默认 location.search
596	 */
597	query_get:function(value, selecter, url)
598	{
599		if (selecter == 'parent') {
600			var query = url != undefined ? url : window.parent.location.search.substring(1);
601		} else {
602			var query = url != undefined ? url : window.location.search.substring(1);
603		}
604		var vars = query.split("&");
605		for (var i = 0; i < vars.length; i++) {
606			var pair = vars[i].split("=");
607			if(pair[0] == value) return pair[1];
608		}
609		return false;
610	},
611	/**
612	 * 获取浏览器滚动条宽度
613	 */
614	 getScrollWidth:function(){
615		var noScroll, scroll, oDiv = document.createElement("DIV");
616		oDiv.style.cssText = "position:absolute; top:-1000px; width:100px; height:100px; overflow:hidden;";
617		noScroll = document.body.appendChild(oDiv).clientWidth;
618		oDiv.style.overflowY = "scroll";
619		scroll = oDiv.clientWidth;
620		document.body.removeChild(oDiv);
621		return noScroll-scroll;
622	},
623
624	/**
625	 * 价格 保留两位小数 向上取整
626	 */
627	ceil_price:function(price){
628		price = parseInt(price.mul(10000));
629		result = (Math.ceil(price.div(100)).div(100)).toFixed(2);
630		return result;
631	},
632
633	getMark: function () {
634		let hash = window.location.hash
635		let mark = '';
636
637		if (hash) mark = hash.substring(1)
638		return mark
639	},
640	//下载
641	DownloadFile: function (fileurl) {
642		//触发锚点
643		let hideElement = document.createElement("a");
644		$(hideElement).attr("target", "_blank");
645		$(hideElement).attr("href", fileurl);
646		hideElement.click();
647	}
648}
649
650//Object => string
651$.toJSON = typeof JSON == "object" && JSON.stringify ? JSON.stringify: function(e) {
652	if (e === null) return "null";
653	var t, n, r, i, s = $.type(e);
654	if (s === "undefined") return undefined;
655	if (s === "number" || s === "boolean") return String(e);
656	if (s === "string") return $.quoteString(e);
657	if (typeof e.toJSON == "function") return $.toJSON(e.toJSON());
658	if (s === "date") {
659		var o = e.getUTCMonth() + 1,
660		u = e.getUTCDate(),
661		a = e.getUTCFullYear(),
662		f = e.getUTCHours(),
663		l = e.getUTCMinutes(),
664		c = e.getUTCSeconds(),
665		h = e.getUTCMilliseconds();
666		o < 10 && (o = "0" + o);
667		u < 10 && (u = "0" + u);
668		f < 10 && (f = "0" + f);
669		l < 10 && (l = "0" + l);
670		c < 10 && (c = "0" + c);
671		h < 100 && (h = "0" + h);
672		h < 10 && (h = "0" + h);
673		return '"' + a + "-" + o + "-" + u + "T" + f + ":" + l + ":" + c + "." + h + 'Z"'
674	}
675	t = [];
676	if ($.isArray(e)) {
677		for (n = 0; n < e.length; n++) t.push($.toJSON(e[n]) || "null");
678		return "[" + t.join(",") + "]"
679	}
680	if (typeof e == "object") {
681		for (n in e) if (hasOwn.call(e, n)) {
682			s = typeof n;
683			if (s === "number") r = '"' + n + '"';
684			else {
685				if (s !== "string") continue;
686				r = $.quoteString(n)
687			}
688			s = typeof e[n];
689			if (s !== "function" && s !== "undefined") {
690				i = $.toJSON(e[n]);
691				t.push(r + ":" + i)
692			}
693		}
694		return "{" + t.join(",") + "}"
695	}
696};
697
698//string => Object
699$.evalJSON = typeof JSON == "object" && JSON.parse ? JSON.parse: function(str) {
700	return eval("(" + str + ")")
701};
702
703var //escape=/["\\\x00-\x1f\x7f-\x9f]/g,
704	meta={
705		'\b': '\\b',
706		'\t': '\\t',
707		'\n': '\\n',
708		'\f': '\\f',
709		'\r': '\\r',
710		'"': '\\"',
711		'\\': '\\\\'
712	},
713	hasOwn=Object.prototype.hasOwnProperty;
714
715$.quoteString = function (str) {
716	if (str.match(escape)) {
717		return '"' + str.replace(escape, function (a) {
718			var c = meta[a];
719			if (typeof c === 'string') {
720				return c;
721			}
722			c = a.charCodeAt();
723			return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16);
724		}) + '"';
725	}
726	return '"' + str + '"';
727};
728
729//单引号双引号用反斜杠转义
730$.quotationMarksTransferred = function (str) {
731	if (typeof(str) !== "string") {
732		str = str.toString();
733	}
734	str = str.replace(/([\\])/g, "\\$1");
735	str = str.replace(/(["])/g, "\\$1");
736	return str;
737}
738
739//解决浮点数精度丢失问题
740$.fn.floatingNumber = function(type, arg1, arg2) {
741	var result = '';
742	if (type == 'addition') {
743		//加法
744		var r1, r2, m;
745		try {
746			r1 = arg1.toString().split(".")[1].length;
747		} catch(e) { r1 = 0; }
748		try {
749			r2 = arg2.toString().split(".")[1].length;
750		} catch(e){ r2 = 0; }
751		m = Math.pow(10, Math.max(r1, r2));
752		result = (Math.round(arg1 * m) + Math.round(arg2 * m)) / m;
753	} else if (type == 'subtraction') {
754		//减法
755		var r1, r2, m, n;
756		try {
757			r1 = arg1.toString().split(".")[1].length;
758		} catch(e) { r1 = 0; }
759		try {
760			r2 = arg2.toString().split(".")[1].length;
761		} catch(e) { r2 = 0; }
762		m = Math.pow(10, Math.max(r1, r2)); //动态控制精度长度
763		n = (r1 >= r2) ? r1 : r2;
764		result = parseFloat(((Math.round(arg1 * m) - Math.round(arg2 * m)) / m).toFixed(n));
765	} else if (type == 'multiply') {
766		//乘法
767		var m = 0, s1 = arg1.toString(), s2 = arg2.toString();
768		try {
769			m += s1.split(".")[1].length;
770		} catch(e) {}
771		try {
772			m += s2.split(".")[1].length;
773		} catch(e) {}
774		result = Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m);
775	} else if (type == 'division') {
776		//除法
777		var t1 = 0, t2 = 0, r1, r2;
778		try {
779			t1 = arg1.toString().split(".")[1].length;
780		} catch(e) {}
781		try {
782			t2 = arg2.toString().split(".")[1].length;
783		} catch(e) {}
784		with (Math) {
785			r1 = Number(arg1.toString().replace(".", ""));
786			r2 = Number(arg2.toString().replace(".", ""));
787			result = (r1 / r2) * pow(10, t2 - t1);
788		}
789	}
790	return result;
791}
792Number.prototype.add = function(arg) {
793	return $('html').floatingNumber('addition', arg, this);
794};
795Number.prototype.sub = function(arg) {
796	return $('html').floatingNumber('subtraction', this, arg);
797};
798Number.prototype.mul = function (arg) {
799	return $('html').floatingNumber('multiply', arg, this);
800};
801Number.prototype.div = function (arg) {
802	return $('html').floatingNumber('division', this, arg);
803};
804
805//价格显示插件
806$.fn.priceShow=function(){
807	var $price=0;
808	$(this).find('.price_data[data]').each(function(){
809		$price=parseFloat($(this).attr('data')).mul(parseFloat(shop_config.currency_rate));
810		if($price>0){
811			$(this).text($('html').iconvPriceFormat($price, 2, '', 1));
812			$(this).parent().find('.currency_data').text(shop_config.currency_symbols);
813		}
814	});
815}
816
817//货币格式显示
818$.fn.iconvPriceFormat = function(price) {
819	var method		= (typeof(arguments[1]) == 'undefined') ? 0 : arguments[1],
820		currency	= (typeof(arguments[2]) == 'undefined') ? '' : arguments[2],
821		is_currency	= (typeof(arguments[3]) == 'undefined') ? 0 : arguments[3],
822		symbol		= shop_config.currency_symbols,
823		price		= parseFloat(price),
824		result		= 0;
825	currency == '' && (currency = shop_config.currency);
826	if (method == 0) {
827		//符号+价格
828		price = parseInt(price.mul(10000));
829		result = (Math.ceil(price.div(100)).div(100)).toFixed(2);
830		is_currency == 1 && currency && (result = $('html').currencyFormat(result, currency));
831		result = symbol + result;
832	} else if (method == 1) {
833		//符号
834		result = symbol;
835	} else {
836		//ä»·æ ¼
837		price = parseInt(price.mul(10000));
838		result = (Math.ceil(price.div(100)).div(100)).toFixed(2);
839		is_currency == 1 && currency && (result = $('html').currencyFormat(result, currency));
840	}
841	return result;
842}
843
844//货币格式显示
845$.fn.currencyFormat=function(price, currency) {
846	let result = 0
847	price = parseFloat(price)
848	price = $('html').currencyFloatPrice(price, currency)
849	switch (currency) {
850		case 'USD':
851		case 'GBP':
852		case 'CAD':
853		case 'AUD':
854		case 'CHF':
855		case 'HKD':
856		case 'ILS':
857		case 'MXN':
858		case 'CNY':
859		case 'SAR':
860		case 'SGD':
861		case 'NZD':
862		case 'AED':
863			result = price.formatMoney(2, '.', ','); break;
864		case 'RUB':
865			result = price.formatMoney(2, ',', ' '); break;
866		case 'EUR':
867		case 'BRL':
868		case 'ARS':
869			result = price.formatMoney(2, ',', '.'); break;
870		case 'CLP':
871		case 'NOK':
872		case 'DKK':
873		case 'COP':
874		case 'VND':
875			result = price.formatMoney(0, '', '.'); break;
876		case 'JPY':
877		case 'SEK':
878		case 'KRW':
879		case 'INR':
880		case 'TWD':
881			result = price.formatMoney(0, '', ','); break;
882		default:
883			result = price.formatMoney(2, '.', ','); break;
884	}
885	return result
886}
887
888Number.prototype.formatMoney = function(places, decimal, thousand) {
889	places = !isNaN(places = Math.abs(places)) ? places : 2;
890	thousand = thousand || ',';
891	decimal = decimal || '.';
892	var number = this,
893		negative = number < 0 ? '-' : '',
894		i = parseInt(number = Math.abs(+number || 0).toFixed(places), 10) + '',
895		j = (j = i.length) > 3 ? j % 3 : 0;
896	return negative + (j ? i.substr(0, j) + thousand : '') + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thousand) + (places ? decimal + Math.abs(number - i).toFixed(places).slice(2) : '');
897};
898
899$.fn.currencyFloatPrice = function(price, currency) {
900	ary = ['CLP', 'NOK', 'DKK', 'COP', 'JPY', 'SEK', 'KRW', 'INR', 'TWD', 'VND']
901	if (global_obj.in_array(currency, ary)) {
902		price = Math.ceil(price);
903	}
904	return price;
905}
906
907/**
908 * 可视化滚动插件
909 *
910 * @param: data[object]	speed:滑动速度,默认300 count:产品可视数量,默认4 isTouch:开启触摸事件,默认0 number:插件序号,默认0 callback:插件回调函数,负责插件加载完毕后执行
911 *
912 * 按钮参考: <a href="javascript:;" rel="nofollow" data-btn-srcoll="插件序号" data-srcoll-direction="方向prev或者next"></a>
913 * 绑定参考: $('#xxx').visualSrcoll({'speed':'500', 'isTouch':1});
914*/
915$.fn.visualSrcoll = function(data) {
916    data = $.extend({
917        obj: $(this),
918        init: function() {
919            this.self       = data.obj.html();
920            this.html       = '';
921            this.number     = data.number;
922            this.index      = 0;
923            this.speed      = data.speed || 300;
924			this.count      = data.count || 4;
925            this.isTouch    = data.isTouch || 0;
926            this.element    = data.obj[0];
927			this.callback	= data.callback || '';
928			if (!this.element) {
929				return false;
930			}
931            if (this.element.addEventListener) {
932                if (this.isTouch == 1) {
933                    this.element.addEventListener('touchstart', this, false);
934                    this.element.addEventListener('touchmove', this, false);
935                    this.element.addEventListener('touchend', this, false);
936                }
937                window.addEventListener('resize', this, false);
938            }
939            if (typeof(data.number) == 'undefined' && $('.box_visual_srcoll').length > 0) {
940                this.number = $('.box_visual_srcoll').length;
941            }
942			if (typeof(data.number) == 'undefined' && $('.box_visual_srcoll').length == 0) {
943				this.number = 0;
944			}
945            this.html += '<div class="srcoll_list">';
946            this.html +=    '<a href="javascript:;" rel="nofollow" class="srcoll_btn srcoll_btn_prev" data-btn-srcoll="' + this.number + '" data-srcoll-direction="prev"></a>';
947            this.html +=    '<a href="javascript:;" rel="nofollow" class="srcoll_btn srcoll_btn_next" data-btn-srcoll="' + this.number + '" data-srcoll-direction="next"></a>';
948            this.html +=    '<div class="srcoll_suit" style="width:100%; overflow:hidden;">';
949            this.html +=        '<div class="srcoll_suit_box">' + this.self + '</div>';
950            this.html +=    '</div>';
951            this.html += '</div">';
952            data.obj.addClass('box_visual_srcoll').attr('data-box-srcoll', this.number).html(this.html);
953            this.setup();
954            this.bind();
955			if ($.isFunction(this.callback)) {
956				this.callback();
957			}
958        },
959        setup: function() {
960            this.suit           = data.obj.find('.srcoll_list .srcoll_suit');
961            this.box            = data.obj.find('.srcoll_list .srcoll_suit_box');
962            this.box.element    = this.box[0];
963            this.children       = this.box.children();
964            this.length         = this.children.length;
965            //this.width          = this.children.eq(0).outerWidth(true);
966			if (this.children.eq(0)[0].currentStyle) {
967				//IE、Opera
968				this.cElement = this.children.eq(0)[0].currentStyle;
969			} else {
970				//FF、Chrome、Safari
971				this.cElement = getComputedStyle(this.children.eq(0)[0], false);
972			}
973			this.width = parseFloat(this.cElement.width) + parseFloat(this.cElement.marginRight) + parseFloat(this.cElement.marginLeft); //精准到小数点
974            this.box.element.style.width = parseFloat(this.length * this.width + 1).toFixed(2) + 'px'; //1px为额外的偏移量
975			for (i = 1; i <= this.length; ++i) {
976				//兼容可视化
977				if ((i * this.width) >= this.suit.width()) {
978					this.count = i;
979					if (((i - .5) * this.width) >= this.suit.width()) {
980						//尚未超过半个
981						this.count = i - 1;
982					}
983					break;
984				}
985			}
986			if (this.count >= this.length) {
987                return false;
988            }
989			this.slide(this.index, 0);
990        },
991        bind: function() {
992            $('*[data-btn-srcoll="' + this.number + '"]').on('click', function() {
993                $(this).data('srcoll-direction') == 'prev' ? data.prev() : data.next();
994            });
995        },
996        prev: function() {
997            if (this.index) {
998                this.slide(this.index - 1, this.speed);
999            }
1000        },
1001        next: function() {
1002            if (this.index < this.length - this.count) {
1003                this.slide(this.index + 1, this.speed);
1004            }
1005        },
1006        slide: function(index, speed) {
1007        	var moveWith = index * this.width;
1008        	var Offset = moveWith + this.suit.width() - this.length * this.width;
1009        	if(Offset > 0) {
1010        		moveWith = moveWith - Offset;
1011        	}
1012            style = this.box.element.style;
1013            style.webkitTransitionDuration = style.MozTransitionDuration = style.msTransitionDuration = style.OTransitionDuration = style.transitionDuration = speed + 'ms';
1014            style.MozTransform = style.webkitTransform = 'translate3d(' + -(moveWith) + 'px, 0, 0)';
1015            style.msTransform = style.OTransform = 'translateX(' + -(moveWith) + 'px)';
1016            this.index = index;
1017        },
1018        handleEvent: function(e) {
1019            var that = this;
1020            if (!e.touches) {
1021                e.touches = new Array(e);
1022                e.scale = false;
1023            }
1024            switch (e.type) {
1025                case 'touchstart': this.touchStart(e); break;
1026                case 'touchmove': this.touchMove(e); break;
1027                case 'touchend': this.touchEnd(e); break;
1028                case 'resize': this.setup(); break;
1029            }
1030        },
1031        touchStart: function(e) {
1032            this.tConfig = {
1033                pageX: e.touches[0].pageX,
1034                pageY: e.touches[0].pageY,
1035				moveX: this.box.element.style.msTransform ? parseFloat(this.box.element.style.msTransform.replace('translateX(', '')) : 0
1036            };
1037            this.movingX = 0;
1038			this.surplus = parseFloat(this.box.width() - this.suit.width()) * -1;
1039			this.tMoveX = 0;
1040        },
1041        touchMove: function(e) {
1042            if (e.touches.length > 1 || e.scale && e.scale !== 1) return;
1043			this.movingX = e.touches[0].pageX - this.tConfig.pageX;
1044			if (this.count == 1) {
1045				this.movingX = this.movingX / (((this.index == 0 && this.movingX > 0) || (this.index == this.length - this.count && this.movingX < 0)) ? (Math.abs(this.movingX) / this.width + 1) : 1); //左右尽头的缓冲效果
1046				style = this.box.element.style;
1047				style.webkitTransitionDuration = style.MozTransitionDuration = style.msTransitionDuration = style.OTransitionDuration = style.transitionDuration = '0ms';
1048				style.MozTransform = style.webkitTransform = 'translate3d(' + (this.movingX - this.index * this.width) + 'px, 0, 0)';
1049				style.msTransform = style.OTransform = 'translateX(' + (this.movingX - this.index * this.width) + 'px)';
1050			} else {
1051				this.tMoveX = parseFloat(this.tConfig.moveX + this.movingX);
1052				if (this.tMoveX > 0 || (this.tMoveX < 0 && this.tMoveX < this.surplus)) {
1053					 //左右尽头的缓冲效果
1054					this.tMoveX = this.tConfig.moveX + (this.movingX / (Math.abs(this.tMoveX) / this.width + 1));
1055				}
1056				style = this.box.element.style;
1057				style.webkitTransitionDuration = style.MozTransitionDuration = style.msTransitionDuration = style.OTransitionDuration = style.transitionDuration = '0ms';
1058				style.MozTransform = style.webkitTransform = 'translate3d(' + this.tMoveX + 'px, 0, 0)';
1059				style.msTransform = style.OTransform = 'translateX(' + this.tMoveX + 'px)';
1060			}
1061        },
1062        touchEnd: function(e) {
1063        	if (this.movingX == 0) return false;  // 原地点击,退出
1064			if (this.count == 1) {
1065				var isSlideHalf = 1; //Math.abs(this.movingX) > this.width / 2,
1066					isBoundary = (this.index == 0 && this.movingX > 0) || (this.index == this.length - this.count && this.movingX < 0); //左右两边尽头
1067				this.slide(this.index + (isSlideHalf && !isBoundary ? (this.movingX < 0 ? 1 : -1) : 0), this.speed); //拖右负数,拖左正数
1068			} else {
1069				this.tMoveX = this.tConfig.moveX + this.movingX;
1070				if (this.tMoveX > 0) {
1071					//左尽头
1072					this.slide(0, 0);
1073				} else if (this.tMoveX < 0 && this.tMoveX < this.surplus) {
1074					//右尽头
1075					this.slide(this.length - 1, 0);
1076				}
1077			}
1078        }
1079    }, data);
1080	data.init();
1081}
1082
1083/**
1084 * 可视化选项卡插件
1085 *
1086 * @param: data[object]	button:事件触发按钮(选择器) box:事件触发盒子(选择器) current:选中相关的样式类名,默认current
1087 *
1088 * 绑定参考: $('#xxx').visualTab({'button':'.category a', 'box':'.box', 'current':'cur FontBgColor', 'box_current':'cur FontBgColor'});
1089 */
1090$.fn.visualTab = function(data) {
1091    data = $.extend({
1092        obj: $(this),
1093        init: function() {
1094            this.button		= data.button;
1095            this.box		= data.box;
1096			this.current	= data.current || 'current';
1097			this.box_current= data.box_current || 'current';
1098			this.selector	= data.obj.find(this.button + ':visible').selector;
1099			this.selectorBox= data.obj.find(this.box).selector;
1100            this.bind();
1101        },
1102		bind: function() {
1103            data.obj.find(this.button + ':visible').on('click', function() {
1104				index = $(this).index(this.selector);
1105                data.display(index);
1106            });
1107        },
1108		display: function(index) {
1109			data.obj.find(this.button).eq(index).addClass(this.current).siblings(this.selector).removeClass(this.current);
1110			data.obj.find(this.box).eq(index).show().addClass(this.box_current).siblings(this.selectorBox).hide().removeClass(this.box_current);
1111        },
1112    }, data);
1113	data.init();
1114}
1115
1116//具有全局标志g的正则表达式的定义方法
1117String.prototype.replaceAll = function(s1, s2) {
1118    return this.replace(new RegExp(s1, "gm"), s2);
1119}
1120
1121// 可视化立即购买插件模块
1122$.fn.VisualBuyNow = function (options) {
1123	$.fn.VisualBuyNow.defaults = {
1124		'item'		:	'.visual_buynow_item',  // 属性item
1125		'button'	:	'.visual_buynow_btn',  // buynow按钮
1126		'current'	:	'current'  // 着色标记
1127	};
1128	let _this = this;
1129	let opts = $.extend({},$.fn.VisualBuyNow.defaults,options);
1130	let tips = function(tips){
1131		if ($(window).width() < 768) {  // 移动端
1132			$('html').tips_box(tips, 'error', '', 1);
1133		} else {
1134			global_obj.new_win_alert(tips);
1135		}
1136	};
1137	// 选择属性
1138	_this.find(opts.item).on('click', function () {
1139		$(this).addClass(opts.current).find('input[type=hidden]').prop('disabled', false);
1140		$(this).siblings().removeClass(opts.current).find('input[type=hidden]').prop('disabled', true);
1141	});
1142	// 点击buynow按钮
1143	_this.find(opts.button).on('click', function () {
1144		if (!_this.find(opts.item + '.current').length) {  // 没有选择属性
1145			tips(lang_obj.cart.batch_buy_option);
1146			return false;
1147		}
1148		let $Formdata = new FormData(_this[0]);
1149		$Formdata.append('IsBuyNow', 1);
1150		$Formdata.append('back', 1);
1151		_this.find(opts.button).attr('disabled', true);
1152		$.ajax({
1153			type: 'POST',
1154			url: '/?do_action=cart.additem',
1155			data: $Formdata,
1156			dataType: 'json',
1157			async: false,
1158			cache: false,
1159			contentType: false,
1160			processData: false,
1161			success: function(data) {
1162				if (data.ret == 1) {
1163					parseInt(shop_config.FbPixelOpen)==1 && $('html').fbq_addtocart(data.msg.item_price);
1164					// Google Add To Cart Event Code
1165					$('html').gtag_addtocart(data.msg.item_price);
1166					parseInt(shop_config.BingTabOpen)==1 && $('html').bing_addtocart();
1167					//BuyNow统计
1168					// analytics_click_statistics(1);//暂时统计为添加购物车事件
1169					setTimeout(function(){
1170						window.location.href=data.msg.location;
1171					}, 800);
1172				} else {
1173					_this.find(opts.button).attr('disabled', false);
1174					tips(data.msg);
1175				}
1176			}
1177		});
1178		return false;
1179	});
1180}
1181
1182$.fn.GetTruePixel = function (options) {
1183	$.fn.GetTruePixel.defaults = {
1184		'type'		:	'width',  // width-宽度 height-高度
1185		'padding'	:	true,  // 是否需要padding
1186		'border'	:	true,  // 是否需要border
1187		'margin'	:	false  // 是否需要margin
1188	};
1189	let _this = this;
1190	let opts = $.extend({},$.fn.GetTruePixel.defaults,options);
1191	let result;
1192	// getBoundingClientRect获取到的是包含border,padding,margin的
1193	if (opts.type == 'width') {
1194		result = _this[0].getBoundingClientRect().width;
1195	} else if (opts.type == 'height') {
1196		result = _this[0].getBoundingClientRect().height;
1197	}
1198	let type_obj = {
1199		'width'		:	{
1200			'margin'	:	{'left':'margin-left', 'right':'margin-right'},
1201			'padding'	:	{'left':'padding-left', 'right':'padding-right'},
1202			'border'	:	{'left':'border-left-width', 'right':'border-right-width'}
1203		},
1204		'height'	:	{
1205			'margin'	:	{'left':'margin-top', 'right':'margin-bottom'},
1206			'padding'	:	{'left':'padding-top', 'right':'padding-bottom'},
1207			'border'	:	{'left':'border-top-width', 'right':'border-bottom-width'}
1208		}
1209	};
1210	if (opts.border == false) {
1211		result = result - parseFloat(_this.css(type_obj[opts.type].border.left)) - parseFloat(_this.css(type_obj[opts.type].border.right));
1212	}
1213	if (opts.padding == false) {
1214		result = result - parseFloat(_this.css(type_obj[opts.type].padding.left)) - parseFloat(_this.css(type_obj[opts.type].padding.right));
1215	}
1216	if (opts.margin == true) {
1217		result = result + parseFloat(_this.css(type_obj[opts.type].margin.left)) + parseFloat(_this.css(type_obj[opts.type].margin.right));
1218	}
1219	return result;
1220}
1221
1222// form对象 转换成 json对象
1223$.fn.serializeObject = function() {
1224	var self = this,
1225		json = {},
1226		push_counters = {},
1227		patterns = {
1228			"validate": /^[a-zA-Z][a-zA-Z0-9_-]*(?:\[(?:\d*|[a-zA-Z0-9_-]+)\])*$/,
1229			"key":      /[a-zA-Z0-9_-]+|(?=\[\])/g,
1230			"push":     /^$/,
1231			"fixed":    /^\d+$/,
1232			"named":    /^[a-zA-Z0-9_-]+$/
1233		};
1234
1235	this.build = function(base, key, value){
1236		base[key] = value;
1237		return base;
1238	};
1239
1240	this.push_counter = function(key){
1241		if(push_counters[key] === undefined){
1242			push_counters[key] = 0;
1243		}
1244		return push_counters[key]++;
1245	};
1246	
1247	$.each($(this).serializeArray(), function(){
1248
1249		// skip invalid keys
1250		if(!patterns.validate.test(this.name)){
1251			return;
1252		}
1253
1254		var k,
1255			keys = this.name.match(patterns.key),
1256			merge = this.value,
1257			reverse_key = this.name;
1258
1259		while((k = keys.pop()) !== undefined){
1260
1261			// adjust reverse_key
1262			reverse_key = reverse_key.replace(new RegExp("\\[" + k +"\\]$"), '');
1263
1264			// push
1265			if(k.match(patterns.push)){
1266				merge = self.build([], self.push_counter(reverse_key), merge);
1267			}
1268
1269			// fixed
1270			else if(k.match(patterns.fixed)){
1271				merge = self.build([], k, merge);
1272			}
1273
1274			// named
1275			else if(k.match(patterns.named)){
1276				merge = self.build({}, k, merge);
1277			}
1278		}
1279
1280		json = $.extend(true, json, merge);
1281	});
1282
1283	return json;
1284};
1285
1286//倒计时插件
1287$.fn.genTimer=function(e){
1288	function u(e){
1289		var t=Math.floor(e/n),
1290			r=Math.floor((e-t*n)/36e5),
1291			i=Math.floor((e-t*n-r*1e3*60*60)/6e4),
1292			s=Math.floor((e-t*n-r*1e3*60*60-i*1e3*60)/1e3);
1293		return {hours:("0"+r).slice(-2), minutes:("0"+i).slice(-2), seconds:("0"+s).slice(-2), dates:t}
1294	}
1295
1296	var t={
1297			beginTime:new Date,
1298			day_label:(shop_config.language_pack=='zh_tw'?"天":"day"),
1299			days_label:(shop_config.language_pack=='zh_tw'?"天":"days"),
1300			unitWord:{hours:":", minutes:":", seconds:""},
1301			day_unitWord:'',
1302			type:"day",
1303			callbackOnlyDatas:!1
1304		},
1305		n=864e5,
1306		r=$.extend({}, t, e),
1307		i=this;
1308
1309	r.targetTime=r.targetTime.replace(/\-/g, "/");
1310	var s=new Date(r.targetTime)-new Date(r.beginTime),
1311	o=function(){
1312		if(s<0){
1313			r.callback.call(i, r.callbackOnlyDatas ? {hours:"00", minutes:"00", seconds:"00",dates:0}: "00"+r.unitWord.hours+"00"+r.unitWord.minutes+"00");
1314			clearInterval(i.interval);
1315		}else{
1316			var e=u(s);
1317			if(r.callbackOnlyDatas) r.callback.call(i, e);
1318			else if(r.type=="day") s>=n*2 ? r.callback.call(i, '<span class="day_count">'+e.dates+(r.day_unitWord?r.day_unitWord:'')+'</span><span class="day">'+r.days_label+'</span><span class="day_seconds">'+e.hours+r.unitWord.hours+e.minutes+r.unitWord.minutes+e.seconds+r.unitWord.seconds+"</span>") : s>=n ? r.callback.call(i, '<span class="day_count">'+e.dates+'</span><span class="day">'+r.day_label+'</span><span class="day_seconds">'+e.hours+r.unitWord.hours+e.minutes+r.unitWord.minutes+e.seconds+r.unitWord.seconds+"</span>") : r.callback.call(i, '<span class="seconds">'+e.hours+r.unitWord.hours+e.minutes+r.unitWord.minutes+e.seconds+r.unitWord.seconds+"</span>");
1319			else if(r.type=="diffNoDay"){
1320				var t=e.hours;
1321				s>=n && (t=Number(e.dates*24)+Number(e.hours));
1322				r.callback.call(i, '<span class="hours">'+t+'</span><span class="miniutes">'+r.unitWord.hours+e.minutes+'</span><span class="senconds">'+r.unitWord.minutes+e.seconds+r.unitWord.seconds+"</span>");
1323			}else if(r.type=="day_separate"){
1324				var day_str='';
1325				if(s>=n*2){
1326					day_str=r.days_label;
1327				}else{
1328					day_str=r.day_label;
1329				}
1330				if(e.dates < 10) e.dates = '0'+e.dates;
1331				r.callback.call(i, (s>=n ? '<span class="day_count"><span class="d">'+String(e.dates).substr(0,1)+'</span><span class="d">'+String(e.dates).substr(1,1)+'</span>'+(e.dates>99 ? '<span class="d">'+String(e.dates).substr(2,1)+'</span>' : '')+'</span><span class="day">'+day_str+'</span>' : '' )+'<span class="day_seconds">'+'<span class="t">'+e.hours.substr(0,1)+'</span><span class="t">'+e.hours.substr(1,1)+'</span><span class="s">'+r.unitWord.hours+'</span><span class="t">'+e.minutes.substr(0,1)+'</span><span class="t">'+e.minutes.substr(1,1)+'</span><span class="s">'+r.unitWord.minutes+'</span><span class="t">'+e.seconds.substr(0,1)+'</span><span class="t">'+e.seconds.substr(1,1)+'</span><span class="s">'+r.unitWord.seconds+'</span></span>');
1332			}else{
1333				var t=e.hours;
1334				s>=n && (t=Number(e.dates*24)+Number(e.hours));
1335				r.callback.call(i, '<span class="seconds">'+t+r.unitWord.hours+e.minutes+r.unitWord.minutes+e.seconds+r.unitWord.seconds+"</span>");
1336			}
1337		}
1338		s-=1e3
1339	};
1340	i.interval=setInterval(o, 1e3);
1341	if (typeof(seckill_timer)=='object'){
1342		seckill_timer.push(i.interval);//秒杀页面计时器ID,防止时间乱跳
1343	}
1344	o();
1345	return this
1346}
1347
1348/**
1349 * 处理时间时区偏移,将Js时区固定为后台设置的时区
1350 */
1351$.fn.processZoneOffsetData = function() {
1352    var time = new Date(),
1353		localOffset = time.getTimezoneOffset(),
1354		totalOffset = localOffset + shop_config.offsetTime,
1355		local = time.getTime(),
1356		serviceTime = local + totalOffset * 60 * 1000
1357
1358	return new Date(serviceTime)
1359}
1360
1361//防抖函数(触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发ï¼
1361Œåˆ™é‡æ–°è®¡ç®—时间。)
1362function debounce(fn, delay) {
1363	let timeout = null
1364	delay = delay || 1000
1365	return function (e) {
1366		clearTimeout(timeout)
1367		timeout = setTimeout(() => { fn.apply(this, arguments) }, delay)
1368	}
1369}
1370//节流函数(当持续触发事件时,保证在一定时间内只调用一次事件处理函数。)
1371function throttle(fn, delay) {
1372	let timer = null
1373	delay = delay || 1000
1374	return function() {
1375		const context = this
1376		if (!timer) {
1377			timer = setTimeout(() => {
1378				fn.apply(context, arguments)
1379				timer = null
1380			}, delay)
1381		}
1382	}
1383}
1384
1385function array_max(arr) {
1386	if (arr && typeof arr ==='object') {
1387		return Object.values(arr).reduce((p, v) => p>v ? p : v)
1388	}
1389	return null
1390}
1391function array_min(arr) {
1392	if (arr && typeof arr ==='object') {
1393		return Object.values(arr).reduce((p, v) => p<v ? p : v)
1394	}
1395	return null
1396}
1397
1398/**
1399 * 文件上传插件的开始上传函数
1400 * 获取图片的宽高
1401 * @param object data
1402 */
1403$.fn.fileUploadAdd = function(data) {
1404    let files = data.files;
1405	for (let i = 0; i < files.length; i++) {
1406		let file = files[i];
1407		let reader = new FileReader();
1408		reader.onload = function(theFile) {
1409			let image = new Image();
1410			image.onload = function() {
1411				file["width"] = this.width;
1412				file["height"] = this.height;
1413			};
1414			image.src = theFile.target.result;
1415		}
1416		reader.readAsDataURL(file);
1417	}
1418}
1419
1420/**
1421 * 递归深拷贝封装
1422 * 
1423 * @param {*} obj 
1424 * @returns 
1425 */
1426$.fn.deepCopy = function(obj) {
1427	var objClone = Array.isArray(obj) ? [] : {};
1428	if (obj && typeof obj === "object") {
1429		for (var key in obj) {
1430			if (obj.hasOwnProperty(key) && obj[key] != undefined) {
1431				// 判断obj子元素是否为对象,如果是,递归复制
1432				if (obj[key].constructor === RegExp) {
1433					objClone[key] = new RegExp(obj[key])
1434				} else if (obj[key] && typeof obj[key] === "object") {
1435					objClone[key] = $.fn.deepCopy(obj[key]);
1436				} else {
1437					// 如果不是,简单复制
1438					objClone[key] = obj[key];
1439				}
1440			}
1441		}
1442	}
1443	return objClone;
1444}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.