/*
* lith 扩展
* Date : 2019-08-22
* Version: 1.6
* author : Lith
* email : serset@yeah.net
*/
/** 扩展 String
* 说明 : 对String类的prototype和类扩充函数: toJsonStr、toJsStr、toXmlStr、decodeXmlStr、html2Text、isNotStr、trim、lTrim、rTrim
* Date : 2017-09-22
* author: Lith
*/
; (function (String) {
//String的去除空格函数
String.prototype.trim = function () { return this.replace(/(^\s*)|(\s*$)/g, ""); };
String.prototype.lTrim = function () { return this.replace(/(^\s*)/g, ""); };
String.prototype.rTrim = function () { return this.replace(/(\s*$)/g, ""); };
String.prototype.toJsonStr = function () {
/// 向json键值对数据的字符串型值 转换。
/// 例如 转换为javascript 代码 var oJson={"name":"ff"}; 中json对象的name属性所对应的值(以双引号包围)。
/// 转换 \b \t \n \f \r \" \\ 为 \\b \\t \\n \\f \\r \\" \\\\
///
/// 转换后的字符串
return this.replace(/\\/g, "\\\\").replace(/\x08/g, "\\b").replace(/\t/g, "\\t").replace(/\n/g, "\\n").replace(/\f/g, "\\f").replace(/\r/g, "\\r").replace(/\"/g, "\\\"");
};
String.prototype.toJsStr = function () {
/// 向javascript的字符串转换。
/// 例如转换为javascript 代码 var str=""; 中str对象所赋的值(以引号包围)。
/// 转换 \b \t \n \f \r \" \' \\ 为 \\b \\t \\n \\f \\r \\" \\' \\\\
///
/// 转换后的字符串
return this.replace(/\\/g, "\\\\").replace(/\x08/g, "\\b").replace(/\t/g, "\\t").replace(/\n/g, "\\n").replace(/\f/g, "\\f").replace(/\r/g, "\\r").replace(/\"/g, "\\\"").replace(/\'/g, "\\\'");
};
String.prototype.toXmlStr = function () {
/// 向xml转换。
/// 例如 转换 <a title="">ok</a> 中a标签的内容体(innerHTML)或 转换 <a title="">ok</a> 中title的值。
/// 转换 & 双引号 < > 为 & " < >(注: 单引号 对应 ' (') ,但有些浏览器不支持,故此函数不转换。)
///
/// 转换后的字符串
return this.replace(/\&/g, "&").replace(/\"/g, """).replace(/\/g, ">");
};
String.prototype.decodeXmlStr = function () {
/// xml属性字符串反向转换(与toXmlStr对应)。
/// 例如 反向转换 <a title="">ok</a> 中a标签的内容体(innerHTML)或 转换 <a title="">ok</a> 中title的值。
/// 转换 & " < > 为 " & < > (注: 单引号 对应 ' (') ,但有些浏览器不支持,故此函数不转换。)
///
/// 转换后的字符串
return this.replace(/\&\;/g, "&").replace(/\"\;/g, "\"").replace(/\<\;/g, "<").replace(/\>\;/g, ">");
};
String.prototype.html2Text = function () {
/// 清除Html格式。例如 : 转换 "<br/>aa<p>ssfa</p>" 为 "aassfa"
/// 转换后的字符串
return this.replace(/<[^>].*?>/g, "");
};
function isNotStr(str) {
return null == str || undefined == str;
}
String.isNotStr = isNotStr;
String.trim = function (str) { return isNotStr(str) ? '' : ('' + str).trim(); };
String.lTrim = function (str) { return isNotStr(str) ? '' : ('' + str).lTrim(); };
String.rTrim = function (str) { return isNotStr(str) ? '' : ('' + str).rTrim(); };
String.toJsonStr = function (str) {
/// 向json键值对数据的字符串型值 转换。
/// 例如 转换为javascript 代码 var oJson={"name":"ff"}; 中json对象的name属性所对应的值(以双引号包围)。
/// 转换 \b \t \n \f \r \" \\ 为 \\b \\t \\n \\f \\r \\" \\\\
///
/// 转换后的字符串
return isNotStr(str) ? '' : ('' + str).toJsonStr();
};
String.toJsStr = function (str) {
/// 向javascript的字符串转换。
/// 例如转换为javascript 代码 var str=""; 中str对象所赋的值(以引号包围)。
/// 转换 \b \t \n \f \r \" \' \\ 为 \\b \\t \\n \\f \\r \\" \\' \\\\
///
/// 转换后的字符串
return isNotStr(str) ? '' : ('' + str).toJsStr();
};
String.toXmlStr = function (str) {
/// 向xml转换。
/// 例如 转换 <a title="">ok</a> 中a标签的内容体(innerHTML)或 转换 <a title="">ok</a> 中title的值。
/// 转换 & 双引号 < > 为 & " < >(注: 单引号 对应 ' (') ,但有些浏览器不支持,故此函数不转换。)
///
/// 转换后的字符串
return isNotStr(str) ? '' : ('' + str).toXmlStr();
};
String.decodeXmlStr = function (str) {
/// xml属性字符串反向转换(与toXmlStr对应)。
/// 例如 反向转换 <a title="">ok</a> 中a标签的内容体(innerHTML)或 转换 <a title="">ok</a> 中title的值。
/// 转换 & " < > 为 " & < > (注: 单引号 对应 ' (') ,但有些浏览器不支持,故此函数不转换。)
///
/// 转换后的字符串
return isNotStr(str) ? '' : ('' + str).decodeXmlStr();
};
String.html2Text = function (str) {
/// 清除Html格式。例如 : 转换 "<br/>aa<p>ssfa</p>" 为 "aassfa"
/// 转换后的字符串
return isNotStr(str) ? '' : ('' + str).html2Text();
};
})(String);
/** 对Date的扩展。扩展 Date.pattern
* 说明 : 将 Date 转化为指定格式的String 月(M)、日(d)、12小时(h)、24小时(H)、分(m)、秒(s)、周(E)、季度(q)
* demo : new Date().pattern("yyyy-MM-dd hh:mm:ss.S") //2006-07-02 08:09:04.423
* Date : 2017-09-22
* author: Lith
*/
; (function (Date) {
/*** 对Date的扩展,将 Date 转化为指定格式的String * 月(M)、日(d)、12小时(h)、24小时(H)、分(m)、秒(s)、周(E)、季度(q)
* 可以用 1-2 个占位符 * 年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字)
* eg:
* (newDate()).pattern("yyyy-MM-dd hh:mm:ss.S")==> 2006-07-02 08:09:04.423
* (new Date()).pattern("yyyy-MM-dd E HH:mm:ss") ==> 2009-03-10 二 20:09:04
* (new Date()).pattern("yyyy-MM-dd EE hh:mm:ss") ==> 2009-03-10 周二 08:09:04
* (new Date()).pattern("yyyy-MM-dd EEE hh:mm:ss") ==> 2009-03-10 星期二 08:09:04
* (new Date()).pattern("yyyy-M-d h:m:s.S") ==> 2006-7-2 8:9:4.18
*/
Date.prototype.pattern = function (fmt) {
var o = {
"M+": this.getMonth() + 1, //月份
"d+": this.getDate(), //日
"h+": this.getHours() % 12 == 0 ? 12 : this.getHours() % 12, //小时
"H+": this.getHours(), //小时
"m+": this.getMinutes(), //分
"s+": this.getSeconds(), //秒
"q+": Math.floor((this.getMonth() + 3) / 3), //季度
"S": this.getMilliseconds() //毫秒
};
var week = {
"0": "/u65e5",
"1": "/u4e00",
"2": "/u4e8c",
"3": "/u4e09",
"4": "/u56db",
"5": "/u4e94",
"6": "/u516d"
};
if (/(y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
}
if (/(E+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, ((RegExp.$1.length > 1) ? (RegExp.$1.length > 2 ? "/u661f/u671f" : "/u5468") : "") + week[this.getDay() + ""]);
}
for (var k in o) {
if (new RegExp("(" + k + ")").test(fmt)) {
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
}
}
return fmt;
}
Date.prototype.addDay = function (dayCount) {
///
/// 偏移的天数,可为负数
this.setTime(this.getTime() + dayCount * (1000 * 60 * 60 * 24));
return this;
};
Date.prototype.addSecond = function (secondCount) {
///
/// 偏移的秒数,可为负数
this.setTime(this.getTime() + secondCount * 1000 );
return this;
};
Date.addDay = function (date, dayCount) {
if ("string" == typeof date) date = new Date(date);
return date.addDay(dayCount);
};
Date.prototype.isWeekend = function () {
///
var week = this.getDay();
if (week == 0 || week == 6) {
return true;
}
return false;
};
Date.isWeekend = function (date) {
if ("string" == typeof date) date = new Date(date);
return date.isWeekend();
};
})(Date);
/** Object.isNullOrEmpty
* 说明 : 判定指定对象是否为null,或空对象(例如:{} )
* demo : Object.isNullOrEmpty({}) //true
* author: Lith
*/
Object.isNullOrEmpty = function (obj) {
/// 判定指定对象是否为null,或空对象(例如:{} )
///
/// 返回指定对象是否为null,或空对象(例如:{} )
if (!obj) return true;
for (var n in obj) { return false; }
return true;
};
/** 对lith的扩展。
* Date : 2017-09-22
* author: Lith
*/
; (function (scope) {
/** 扩展 lith.stringify
* 说明 : 把json(object 或 Array)转换为字符串。参照 /native/json2.js
* Date : 2017-09-22
* author: Lith
*/
; (function (scope) {
var JSON = {};
(function () {
'use strict';
function f(n) {
// Format integers to have at least two digits.
return n < 10 ? '0' + n : n;
}
if (typeof Date.prototype.toJSON !== 'function') {
Date.prototype.toJSON = function () {
return isFinite(this.valueOf())
? this.getUTCFullYear() + '-' +
f(this.getUTCMonth() + 1) + '-' +
f(this.getUTCDate()) + 'T' +
f(this.getUTCHours()) + ':' +
f(this.getUTCMinutes()) + ':' +
f(this.getUTCSeconds()) + 'Z'
: null;
};
String.prototype.toJSON =
Number.prototype.toJSON =
Boolean.prototype.toJSON = function () {
return this.valueOf();
};
}
var cx,
escapable,
gap,
indent,
meta,
rep;
function quote(string) {
// If the string contains no control characters, no quote characters, and no
// backslash characters, then we can safely slap some quotes around it.
// Otherwise we must also replace the offending characters with safe escape
// sequences.
escapable.lastIndex = 0;
return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
var c = meta[a];
return typeof c === 'string'
? c
: '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
}) + '"' : '"' + string + '"';
}
function str(key, holder) {
// Produce a string from holder[key].
var i, // The loop counter.
k, // The member key.
v, // The member value.
length,
mind = gap,
partial,
value = holder[key];
// If the value has a toJSON method, call it to obtain a replacement value.
if (value && typeof value === 'object' &&
typeof value.toJSON === 'function') {
value = value.toJSON(key);
}
// If we were called with a replacer function, then call the replacer to
// obtain a replacement value.
if (typeof rep === 'function') {
value = rep.call(holder, key, value);
}
// What happens next depends on the value's type.
switch (typeof value) {
case 'string':
return quote(value);
case 'number':
// JSON numbers must be finite. Encode non-finite numbers as null.
return isFinite(value) ? String(value) : 'null';
case 'boolean':
case 'null':
// If the value is a boolean or null, convert it to a string. Note:
// typeof null does not produce 'null'. The case is included here in
// the remote chance that this gets fixed someday.
return String(value);
// If the type is 'object', we might be dealing with an object or an array or
// null.
case 'object':
// Due to a specification blunder in ECMAScript, typeof null is 'object',
// so watch out for that case.
if (!value) {
return 'null';
}
// Make an array to hold the partial results of stringifying this object value.
gap += indent;
partial = [];
// Is the value an array?
if (Object.prototype.toString.apply(value) === '[object Array]') {
// The value is an array. Stringify every element. Use null as a placeholder
// for non-JSON values.
length = value.length;
for (i = 0; i < length; i += 1) {
partial[i] = str(i, value) || 'null';
}
// Join all of the elements together, separated with commas, and wrap them in
// brackets.
v = partial.length === 0
? '[]'
: gap
? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']'
: '[' + partial.join(',') + ']';
gap = mind;
return v;
}
// If the replacer is an array, use it to select the members to be stringified.
if (rep && typeof rep === 'object') {
length = rep.length;
for (i = 0; i < length; i += 1) {
if (typeof rep[i] === 'string') {
k = rep[i];
v = str(k, value);
if (v) {
partial.push(quote(k) + (gap ? ': ' : ':') + v);
}
}
}
} else {
// Otherwise, iterate through all of the keys in the object.
for (k in value) {
if (Object.prototype.hasOwnProperty.call(value, k)) {
v = str(k, value);
if (v) {
partial.push(quote(k) + (gap ? ': ' : ':') + v);
}
}
}
}
// Join all of the member texts together, separated with commas,
// and wrap them in braces.
v = partial.length === 0
? '{}'
: gap
? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}'
: '{' + partial.join(',') + '}';
gap = mind;
return v;
}
}
// If the JSON object does not yet have a stringify method, give it one.
if (typeof JSON.stringify !== 'function') {
escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
meta = { // table of character substitutions
'\b': '\\b',
'\t': '\\t',
'\n': '\\n',
'\f': '\\f',
'\r': '\\r',
'"': '\\"',
'\\': '\\\\'
};
JSON.stringify = function (value) {
// The stringify method takes a value and an optional replacer, and an optional
// space parameter, and returns a JSON text. The replacer can be a function
// that can replace values, or an array of strings that will select the keys.
// A default replacer method can be provided. Use of the space parameter can
// produce text that is more easily readable.
var replacer = arguments[1], space = arguments[2];
var i;
gap = '';
indent = '';
// If the space parameter is a number, make an indent string containing that
// many spaces.
if (typeof space === 'number') {
for (i = 0; i < space; i += 1) {
indent += ' ';
}
// If the space parameter is a string, it will be used as the indent string.
} else if (typeof space === 'string') {
indent = space;
}
// If there is a replacer, it must be a function or an array.
// Otherwise, throw an error.
rep = replacer;
if (replacer && typeof replacer !== 'function' &&
(typeof replacer !== 'object' ||
typeof replacer.length !== 'number')) {
throw new Error('JSON.stringify');
}
// Make a fake root object containing our value under the key of ''.
// Return the result of stringifying the value.
return str('', { '': value });
};
}
// If the JSON object does not yet have a parse method, give it one.
if (typeof JSON.parse !== 'function') {
cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
JSON.parse = function (text, reviver) {
// The parse method takes a text and an optional reviver function, and returns
// a JavaScript value if the text is a valid JSON text.
var j;
function walk(holder, key) {
// The walk method is used to recursively walk the resulting structure so
// that modifications can be made.
var k, v, value = holder[key];
if (value && typeof value === 'object') {
for (k in value) {
if (Object.prototype.hasOwnProperty.call(value, k)) {
v = walk(value, k);
if (v !== undefined) {
value[k] = v;
} else {
delete value[k];
}
}
}
}
return reviver.call(holder, key, value);
}
// Parsing happens in four stages. In the first stage, we replace certain
// Unicode characters with escape sequences. JavaScript handles many characters
// incorrectly, either silently deleting them, or treating them as line endings.
text = String(text);
cx.lastIndex = 0;
if (cx.test(text)) {
text = text.replace(cx, function (a) {
return '\\u' +
('0000' + a.charCodeAt(0).toString(16)).slice(-4);
});
}
// In the second stage, we run the text against regular expressions that look
// for non-JSON patterns. We are especially concerned with '()' and 'new'
// because they can cause invocation, and '=' because it can cause mutation.
// But just to be safe, we want to reject all unexpected forms.
// We split the second stage into 4 regexp operations in order to work around
// crippling inefficiencies in IE's and Safari's regexp engines. First we
// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
// replace all simple value tokens with ']' characters. Third, we delete all
// open brackets that follow a colon or comma or that begin the text. Finally,
// we look to see that the remaining characters are only whitespace or ']' or
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
if (/^[\],:{}\s]*$/
.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
.replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
// In the third stage we use the eval function to compile the text into a
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
// in JavaScript: it can begin a block or an object literal. We wrap the text
// in parens to eliminate the ambiguity.
j = eval('(' + text + ')');
// In the optional fourth stage, we recursively walk the new structure, passing
// each name/value pair to a reviver function for possible transformation.
return typeof reviver === 'function'
? walk({ '': j }, '')
: j;
}
// If the text is not JSON parseable, then a SyntaxError is thrown.
throw new SyntaxError('JSON.parse');
};
}
}());
/// 把json转换为字符串
scope.stringify = JSON.stringify;
})(scope);
/** 扩展 lith.stringNson
* 说明 : 把nson转换为字符串(目前相对json扩充了function类型。值可为function类型)
* Date : 2018-08-02
* author: Lith
*/
; (function (scope) {
// var toJsonStr = String.toJsonStr;
// function dateToStr(v) { return v.pattern('"yyyy-MM-dd hh:mm:ss"'); }
function toJsonStr(v) {
/// 向json键值对数据的字符串型值 转换。
/// 例如 转换为javascript 代码 var oJson={"name":"ff"}; 中json对象的name属性所对应的值(以双引号包围)。
/// 转换 \b \t \n \f \r \" \\ 为 \\b \\t \\n \\f \\r \\" \\\\
///
/// 转换后的字符串
return v.replace(/\\/g, "\\\\").replace(/\x08/g, "\\b").replace(/\t/g, "\\t").replace(/\n/g, "\\n").replace(/\f/g, "\\f").replace(/\r/g, "\\r").replace(/\"/g, "\\\"");
}
function dateToStr(d) {
function f(n) {
return n < 10 ? '0' + n : n;
}
return d.getUTCFullYear() + '-' +
f(d.getUTCMonth() + 1) + '-' +
f(d.getUTCDate()) + ' ' +
f(d.getUTCHours()) + ':' +
f(d.getUTCMinutes()) + ':' +
f(d.getUTCSeconds());
}
function arrayToStr(array) {
var str = '[';
for (var p in array) str += stringify(array[p]) + ',';
if (1 == str.length) return '[]';
return str.slice(0, -1) + ']';
}
function objectToStr(object) {
if (!object) return 'null';
var str = '{';
for (var p in object) str += '"' + toJsonStr(p) + '":' + stringify(object[p]) + ',';
if (1 == str.length) return '{}';
return str.slice(0, -1) + '}';
}
function stringify(v) {
if ('string' == typeof (v)) return '"' + toJsonStr(v) + '"';
if ('object' == typeof (v))
if (Object.prototype.toString.apply(v) === '[object Array]') return arrayToStr(v);
else if (v instanceof Date) return dateToStr(v);
else return objectToStr(v);
return '' + v;
}
scope.stringNson = stringify;
})(scope);
/** 扩展 lith.math (lith.math.mod lith.math.guid)
* Date : 2017-01-04
* author:Lith
*/
; (function (scope) {
var objName = 'math';
var obj = (scope[objName] || (scope[objName] = {}));
obj.mod = function (a, b) {
/// a对b取模(余数),结果始终为非负数。 mod(-1,10)结果为9 。(b符号无意义,若为0则始终返回0)
/// sss
/// s
///
return b == 0 ? 0 : (a < 0 ? (b - ((-a) % b)) : a % b);
};
obj.guid = function (len, radix) {
///
/// 获取guid。(若不传参数,则为 rfc4122, version 4 form)
/// lith.math.guid() // "3D6F0925-9535-4A30-9F70-EE57B77095B1"
/// lith.math.guid(8, 2) // "11000101"
///
/// 可不指定
/// 可不指定,默认16
///
var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
var uuid = [], i;
radix = radix || chars.length;
if (len) {
// Compact form
for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix];
} else {
// rfc4122, version 4 form
var r;
// rfc4122 requires these characters
uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
uuid[14] = '4';
// Fill in random data. At i==19 set the high bits of clock sequence as
// per rfc4122, sec. 4.1.5
for (i = 0; i < 36; i++) {
if (!uuid[i]) {
r = 0 | Math.random() * 16;
uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
}
}
}
return uuid.join('');
};
})(scope);
/** 扩展 EventForHit
* Date : 2017-09-22
* author:Lith
*/
scope.EventForHit = function () {
/// demo:
/// var event=new lith.EventForHit();
/// event.doAfterHit(func1);
/// event.onHit(); //会调用 func1
/// event.doAfterHit(func2); //会调用 func2
/// event.hited=false;
/// event.doAfterHit(func3);
/// event.doAfterHit(func4);
/// event.onHit(); //会调用 func3,func4
///
/// var event=new lith.EventForHit();
/// event.doAfterHit(func1);
/// event.addHit('a');event.addHit('b');
/// event.onHit('a');
/// event.onHit('b'); //会调用 func1
///
/// event.doAfterHit(func1);
/// event.clearCallback(); // 会清除func1
/// event.doAfterHit(func2);
/// event.onHit(); //会调用 func2
///
var cbList;
this.hited = false;
this.doAfterHit = function (callback) {
if (this.hited) {
callback();
} else {
if (cbList) cbList.push(callback);
else cbList = [callback];
}
};
var hitNames;
this.addHit = function (hitName) {
if (!hitNames) hitNames = {};
hitNames[hitName] = true;
};
function Object_isNullOrEmpty(obj) {
/// 判定指定对象是否为null,或空对象(例如:{} )
///
/// 返回指定对象是否为null,或空对象(例如:{} )
if (!obj) return true;
for (var n in obj) { return false; }
return true;
}
this.onHit = function (hitName) {
if (hitName) {
if (hitNames) {
delete hitNames[hitName];
}
}
if (!Object_isNullOrEmpty(hitNames)) {
return;
}
this.hited = true;
if (cbList) {
for (var t in cbList) {
cbList[t]();
}
cbList = null;
}
};
this.clearCallback = function () {
cbList = null;
};
};
/** 扩展 override、virtual
* Date : 2017-09-22
* author:Lith
*/
; (function (scope) {
scope.override = function (object, funcName, func) {
///
///
/// 用this函数(func)重写对象(object)的base函数(funcName),base函数作为this函数的参数传入
/// 注:调用base函数的建议方式为 base.apply(this,arguments) 或 base.call(this,p1,p2...)
///
/// 对象,若不指定(例如null)则参数funcName必须为函数
/// 函数 或 在对象(object)中的函数名称
/// 重写的函数
/// true:旧函数作为新函数的第一个参数传入; 其他:旧函数会作为新函数的最后一个参数传入
/// 调用的次数(若为正数则在调用times次后 再次调用时就调用base函数)(若为数字,会先取整)
/// 是否强制base参数为函数,若funcName对应的值不为函数,则把base转换为返回funcName对应的值的无参函数
///
///
///
/// 用this函数(func)重写对象(object)的base函数(funcName),base函数作为this函数的参数传入
/// 注:调用base函数的建议方式为 base.apply(this,arguments) 或 base.call(this,p1,p2...)
///
/// 对象,若不指定(例如null)则参数funcName必须为函数
/// 函数 或 在对象(object)中的函数名称
/// 重写的函数
///
/// param.baseAsFirstParam[bool]: true:旧函数作为新函数的第一个参数传入; 其他:旧函数会作为新函数的最后一个参数传入
/// param.times[int]: 调用的次数(若为正数则在调用times次后 再次调用时就调用base函数)(若为数字,会先取整)
/// param.forceBaseToFunc[bool]: 是否强制base参数为函数,若funcName对应的值不为函数,则把base转换为返回funcName对应的值的无参函数
/// Demo: {},{baseAsFirstParam:true,times:0,forceBaseToFunc:true},{times:1,forceBaseToFunc:true}
///
///
var param = arguments[3];
if (!param || 'object' != typeof (param)) {
param = { baseAsFirstParam: param, times: arguments[4], forceBaseToFunc: arguments[5] };
}
var baseValue, base, funcCallBase;
if ('function' == typeof (funcName)) {
funcCallBase = base = baseValue = funcName;
} else if (object && 'object' == typeof (object)) {
if ('function' == typeof (baseValue = object[funcName])) {
funcCallBase = base = baseValue;
} else {
base = param.forceBaseToFunc ? (funcCallBase = function () { return baseValue; }) : baseValue;
}
} else {
throw new Error('override参数不合法,没有正确指定base函数');
}
if (isNaN(param.times)) param.times = -1;
else param.times = parseInt(param.times);
var funcCur = function () {
var args = Array.prototype.slice.call(arguments);
if (true == param.baseAsFirstParam) {
args.splice(0, 0, base);
} else {
args.push(base);
}
var ret = func.apply(this, args);
if (param.times > 0) {
param.times--;
if (0 >= param.times) {
funcCur = funcCallBase;
}
}
return ret;
}
var funcRet = function () { return funcCur.apply(this, arguments); };
if (object && 'object' == typeof (object)) object[funcName] = funcRet;
return funcRet;
};
scope.overrideEasyBase = function (object, funcName, func) {
///
///
/// 用this函数(func)重写对象(object)的base函数(funcName),base函数作为this函数的参数传入
/// 若base对应的值不为函数,则把base转换为返回对应的值的无参函数
/// 调用base函数时,函数所在的this对象始终为this函数所在的对象(其参数根据ignoreBaseArgs决定使用this函数的参数还是调用时传入的参数)。
///
/// 对象,若不指定(例如null)则参数funcName必须为函数
/// 函数 或 在对象(object)中的函数名称
/// 重写的函数
/// true:旧函数作为新函数的第一个参数传入; 其他:旧函数会作为新函数的最后一个参数传入
/// 调用的次数(若为正数则在调用times次后 再次调用时就调用base函数)(若为数字,会先取整)
/// true:忽略base函数调用时传入的参数(无论调用base函数时是否指定参数)而使用this函数的原始参数 其他(false 或 undifined等):使用base函数调用时传入的参数
///
///
///
/// 用this函数(func)重写对象(object)的base函数(funcName),base函数作为this函数的参数传入
/// 若base对应的值不为函数,则把base转换为返回对应的值的无参函数
/// 调用base函数时,函数所在的this对象始终为this函数所在的对象(其参数根据ignoreBaseArgs决定使用this函数的参数还是调用时传入的参数)。
///
/// 对象,若不指定(例如null)则参数funcName必须为函数
/// 函数 或 在对象(object)中的函数名称
/// 重写的函数
///
/// param.baseAsFirstParam[bool]: true:旧函数作为新函数的第一个参数传入; 其他:旧函数会作为新函数的最后一个参数传入
/// param.times[int]: 调用的次数(若为正数则在调用times次后 再次调用时就调用base函数)(若为数字,会先取整)
/// param.ignoreBaseArgs[bool] true:忽略base函数调用时传入的参数(无论调用base函数时是否指定参数)而使用this函数的原始参数 其他(false 或 undifined等):使用base函数调用时传入的参数
/// Demo: {},{baseAsFirstParam:true,times:0,ignoreBaseArgs:false},{times:1}
///
///
var param = arguments[3];
if (!param || 'object' != typeof (param)) {
param = { baseAsFirstParam: param, times: arguments[4], ignoreBaseArgs: arguments[5] };
}
var baseValue, funcCallBase;
if ('function' == typeof (funcName)) {
funcCallBase = baseValue = funcName;
} else if (object && 'object' == typeof (object)) {
if ('function' == typeof (baseValue = object[funcName])) {
funcCallBase = baseValue;
} else {
funcCallBase = function () { return baseValue; }
}
} else {
throw new Error('overrideEasyBase参数不合法,没有正确指定base函数');
}
if (isNaN(param.times)) param.times = -1;
else param.times = parseInt(param.times);
var funcCur = function () {
var args = Array.prototype.slice.call(arguments);
var self = this, self_args = arguments, base = function () {
return funcCallBase.apply(self, (true == param.ignoreBaseArgs ? self_args : arguments));
}
if (true == param.baseAsFirstParam) {
args.splice(0, 0, base);
} else {
args.push(base);
}
var ret = func.apply(this, args);
if (param.times > 0) {
param.times--;
if (0 >= param.times) {
funcCur = funcCallBase;
}
}
return ret;
}
var funcRet = function () { return funcCur.apply(this, arguments); };
if (object && 'object' == typeof (object)) object[funcName] = funcRet;
return funcRet;
};
scope.virtual = function (object, funcName, func) {
///
/// 继承函数,在调用新函数时会调用旧函数
/// 对象,若不指定(例如null)则参数funcName必须为函数
/// 函数 或 在对象(object)中的函数名称
/// 重写的函数
/// 是否先调用重写的函数. true:先调用重写的函数,后调用base函数; 其他(例如false): 先调用base函数,后调用重写的函数。
/// 是否用base函数的返回值作为返回值。 true:base函数的返回值作为返回值; 其他(例如false): 重写函数的返回值作为返回值。
/// 调用的次数(若为正数则在调用times次后 再次调用时就调用base函数)(若为数字,会先取整)
///
///
/// 继承函数,在调用新函数时会调用旧函数
/// 对象,若不指定(例如null)则参数funcName必须为函数
/// 函数 或 在对象(object)中的函数名称
/// 重写的函数
///
/// param.callThisFirst: 是否先调用重写的函数. true:先调用重写的函数,后调用base函数; 其他(例如false): 先调用base函数,后调用重写的函数。
/// param.retBase: 是否用base函数的返回值作为返回值。 true:base函数的返回值作为返回值; 其他(例如false): 重写函数的返回值作为返回值。
/// param.times:调用的次数(若为正数则在调用times次后 再次调用时就调用base函数)(若为数字,会先取整)
/// Demo: {},{callThisFirst:false,retBase:true,times:0},{retBase:true,times:1}
///
///
var param = arguments[3];
if (!param || 'object' != typeof (param)) {
param = { callThisFirst: param, retBase: arguments[4], times: arguments[5] };
}
var baseValue, funcCallBase;
if ('function' == typeof (funcName)) {
funcCallBase = baseValue = funcName;
} else if (object && 'object' == typeof (object)) {
if ('function' == typeof (baseValue = object[funcName])) {
funcCallBase = baseValue;
} else {
funcCallBase = function () { return baseValue; };
}
} else {
throw new Error('virtual参数不合法,没有正确指定base函数');
}
if (isNaN(param.times))
param.times = -1;
else
param.times = parseInt(param.times);
var funcCur = function () {
var thisRet, baseRet;
if (true == param.callThisFirst)
thisRet = func.apply(this, arguments);
baseRet = funcCallBase.apply(this, arguments);
if (true != param.callThisFirst)
thisRet = func.apply(this, arguments);
if (param.times > 0) {
param.times--;
if (0 >= param.times) {
funcCur = funcCallBase;
}
}
return true == param.retBase ? baseRet : thisRet;
};
var funcRet = function () { return funcCur.apply(this, arguments); };
if (object && 'object' == typeof (object)) object[funcName] = funcRet;
return funcRet;
};
scope.virtualBaseFirstRetBase = function (object, funcName, func) {
/// 用新函数func重写对象object的函数funcName,先调用base函数,再调用this函数,返回base函数的返回值
/// 对象,若不指定(例如null)则参数funcName必须为函数
/// 函数 或 在对象(object)中的函数名称
/// 重写的函数
return scope.virtual(object, funcName, func, { callThisFirst: false, retBase: true });
};
scope.virtualBaseFirstRetThis = function (object, funcName, func) {
/// 用新函数func重写对象object的函数funcName,先调用base函数,再调用this函数,返回this函数的返回值
/// 对象,若不指定(例如null)则参数funcName必须为函数
/// 函数 或 在对象(object)中的函数名称
/// 重写的函数
return scope.virtual(object, funcName, func, { callThisFirst: false, retBase: false });
};
scope.virtualThisFirstRetBase = function (object, funcName, func) {
/// 用新函数func重写对象object的函数funcName,先调用this函数,再调用base函数,返回base函数的返回值
/// 对象,若不指定(例如null)则参数funcName必须为函数
/// 函数 或 在对象(object)中的函数名称
/// 重写的函数
return scope.virtual(object, funcName, func, { callThisFirst: true, retBase: true });
};
scope.virtualThisFirstRetThis = function (object, funcName, func) {
/// 用新函数func重写对象object的函数funcName,先调用this函数,再调用base函数,返回this函数的返回值
/// 对象,若不指定(例如null)则参数funcName必须为函数
/// 函数 或 在对象(object)中的函数名称
/// 重写的函数
return scope.virtual(object, funcName, func, { callThisFirst: true, retBase: false });
};
})(scope['function'] || (scope['function'] = {}));
/** 扩展 lith.localStorage 客户端存储
* Date : 2019-04-17
* author:Lith
*/
; (function (scope) {
var objName = 'localStorage';
var obj = scope[objName] || (scope[objName] = {});
obj.set = function (key, value, expireSeconds) {
/// 存储值到对应的key中
/// 索引码或者名称,需要唯一.
/// 具体的内容值
/// 过期秒数,不传则永不失效
var data = { value: value };
if (expireSeconds && expireSeconds > 0) {
data.expireTime = new Date().addSecond(expireSeconds).getTime();
}
try {
localStorage.setItem(key, JSON.stringify(data));
} catch (e) {
}
}
obj.get = function (key) {
/// 根据对应的key返回对应值,找不到返回null
/// 索引码或者名称,需要唯一.
try {
var data = localStorage.getItem(key);
if (!data) return null;
data = JSON.parse(data);
if (data.expireTime) {
if (data.expireTime < new Date().getTime()) {
localStorage.removeItem(key);
return null;
}
}
return data.value;
} catch (e) {
return null;
}
}
obj.delete = function (key) {
/// 根据对应的key删除值
/// 索引码或者名称,需要唯一.
localStorage.removeItem(key);
}
})(scope);
/** 扩展 lith.cookie 客户端缓存
* Date : 2017-09-22
* author:Lith
*/
; (function (scope) {
var objName = 'cookie';
var obj = scope[objName] || (scope[objName] = {});
obj.set = function (name, value, expires) {
/// 存储值到对应的key中
/// 索引码或者名称,需要唯一.
/// 具体的内容值
/// 有效期到期时间,不传则默认有效期为1天.例如:new Date().getTime(),秒数值:1496305713020
if (!expires) {
var Days = 1;
var exp = new Date();
expires = exp.setTime(exp.getTime() + Days * 24 * 60 * 60 * 1000);
expires = new Date(expires);
}
document.cookie = name + "=" + escape(value) + ";path=/;expires=" + expires.toGMTString();
}
obj.get = function (name) {
/// 根据对应的key返回对应存放在cookie中的值,找不到返回null
/// 索引码或者名称,需要唯一.
var arr;
var reg = new RegExp("(^|)" + name + "=([^;]*)(;|$)")
if (arr = document.cookie.match(reg))
return unescape(arr[2]);
else
return null;
}
obj.delete = function (name) {
/// 根据对应的key删除存放在cookie中的值
/// 索引码或者名称,需要唯一.
var exp = new Date();
exp.setTime(exp.getTime() - 1);
exp = new Date(exp);
var cval = this.get(name);
if (cval)
document.cookie = name + "=" + escape(cval) + ";expires=" + exp.toGMTString();
}
})(scope);
/** 扩展 scope.browse 浏览器类别
* Date : 2017-09-22
* author:Lith
*/
; (function (scope) {
scope.browser = function () {
try {
var userAgent = navigator.userAgent.toLowerCase();
// Figure out what browser is being used
var browser = {
version: (userAgent.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [])[1],
safari: /webkit/.test(userAgent),
opera: /opera/.test(userAgent),
msie: /msie/.test(userAgent) && !/opera/.test(userAgent),
mozilla: /mozilla/.test(userAgent) && !/(compatible|webkit)/.test(userAgent)
};
return browser;
} catch (e) {
return {};
}
}
})(scope);
/** 扩展 lith.document(动态加载 js 和 css,打开新窗口,获取url参数等)
* Date : 2018-08-02
* author:Lith
*/
; (function (scope) {
var objName = 'document';
var obj = scope[objName] || (scope[objName] = {});
var toXmlStr = function toXmlStr(str) {
/// 向xml转换。
/// 例如 转换 <a title="">ok</a> 中a标签的内容体(innerHTML)或 转换 <a title="">ok</a> 中title的值。
/// 转换 & 双引号 < > 为 & " < >(注: 单引号 对应 ' (') ,但有些浏览器不支持,故此函数不转换。)
///
/// 转换后的字符串
return str.replace(/\&/g, "&").replace(/\"/g, """).replace(/\/g, ">");
};
obj.url_GetArg = function (src, key) {
/// 获取当前src中的参数
/// demo: var jsName=lith.document.url_GetArg("aaa.html?a=1&b=2",'name');
///
/// 例如:"?a=1&b=2"
/// 若不为字符串,则返回把所有参数做为键值对的对象。若为字符串,且获取不到,则返回 null
///
if (arguments.length == 1) {
key = src;
src = location.search;
}
if ('string' == typeof key) {
var v = (src.match(new RegExp("(?:\\?|&)" + key + "=(.*?)(?=&|$)")) || ['', null])[1];
return v && decodeURIComponent(v);
} else {
var reg = /(?:\?|&)(.*?)=(.*?)(?=&|$)/g, temp, res = {};
while ((temp = reg.exec(src)) != null)
res[temp[1]] = decodeURIComponent(temp[2]);
return res;
}
//var src = location.search;
//if (src.length < 2 || src.charAt(0) != '?') {
// return null;
//}
//var params = src.substring(1).split('&');
//var ps = null;
//for (var i in params) {
// ps = params[i].split('=');
// if (decodeURIComponent(ps[0]) == name) {
// return decodeURIComponent(ps[1]);
// }
//}
//return null;
};
obj.script_getArg = function (key) {
/// 返回所在脚本src参数。
/// demo: var jsName=lith.document.script_getArg('name');
/// 不要在方法中调用此方法,否则可能始终获取的是最后一个js的文件的参数
///
/// 若不为字符串,则返回把所有参数做为键值对的对象。若为字符串,且获取不到,则返回 null
////假如上面的js是在这个js1.js的脚本中
var scripts = document.getElementsByTagName("script"),
//因为当前dom加载时后面的script标签还未加载,所以最后一个就是当前的script
script = scripts[scripts.length - 1],
src = script.src;
return obj.url_GetArg(src, key);
};
obj.openWin = function (html) {
/// 在新页面中显示html
/// html 代码
///
var oWin = window.open('');
oWin.document.write(html);
return oWin;
};
obj.openForm = function (param) {
/// 在新页面中新建Form,发送请求。
/// demo:lith.document.openForm({url:'http://www.a.com',reqParam:{a:3},type:'post'});
///
///
/// demo:{url:'http://www.a.com',reqParam:{a:3},type:'post'}
/// url[string]:要打开的链接地址。
/// reqParam[object]:请求参数。
/// type[string]:请求方式。可为'get'、'post'、'put'等,不指定则为get。
///
///
/// 。
///
///
var html = '请稍等 ';
html += '请稍等 ...
';
html += '';
html += '
document.write('');
}
function loadJs_AfterDocumentLoaded(jsSrc) {
/// 载入js文件。在文档已经加载完成后载入js文件。
/// 例如:"/Scripts/jquery-easyui/jquery.easyui.min.js"
var eJs = document.createElement('script');
eJs.type = 'text/javascript';
eJs.language = 'javascript';
eJs.src = jsSrc;
document.getElementsByTagName("head")[0].appendChild(eJs);
}
};
obj.loadCss = function (cssSrc) {
/// 载入css文件。在文档加载过程中或已经加载完成后载入css文件。
/// 例如:"/Scripts/jquery-easyui/themes/icon.css"
if (document.readyState == "loading") {
loadCss_BeforeDocumentLoaded(cssSrc);
} else {
loadCss_AfterDocumentLoaded(cssSrc);
}
function loadCss_BeforeDocumentLoaded(cssSrc) {
/// 载入css文件。在文档加载过程中载入css文件。
/// 例如:"/Scripts/jquery-easyui/themes/icon.css"
//
document.write('');
}
function loadCss_BeforeDocumentLoaded(cssSrc) {
/// 载入css文件。在文档已经加载完成后载入css文件。
/// 例如:"/Scripts/jquery-easyui/themes/icon.css"
var eCss = document.createElement('link');
eCss.rel = 'Stylesheet';
eCss.type = 'text/css';
eCss.href = cssSrc;
document.getElementsByTagName("head")[0].appendChild(eCss);
}
};
obj.addCss = function (cssText) {
/// 添加新的CSS样式节点。demo: lith.document.addCss('.header{ background-color:#8f8;}');
///
var style = document.createElement('style'); //创建一个style元素
style.type = 'text/css'; //这里必须显示设置style元素的type属性为text/css,否则在ie中不起作用
var head = document.head || document.getElementsByTagName('head')[0]; //获取head元素
head.appendChild(style); //把创建的style元素插入到head中
if (style.styleSheet) { //IE
var func = function () {
try {
//防止IE中stylesheet数量超过限制而发生错误
style.styleSheet.cssText = cssText;
} catch (e) { }
}
//如果当前styleSheet还不能用,则放到异步中则行
if (style.styleSheet.disabled) {
setTimeout(func, 10);
} else {
func();
}
} else { //w3c
//w3c浏览器中只要创建文本节点插入到style元素中就行了
var textNode = document.createTextNode(cssText);
style.appendChild(textNode);
}
};
})(scope);
})('undefined' === typeof (lith) ? lith = {} : lith);