underscore.extend.js
/**
* 基于underscore的扩展
* @module lib/underscoreExtend
*/
(function() { // 全局可能用到的变量
var arr = [];
var slice = arr.slice;
/**
* js的继承,默认为两个参数
* @public
* @name inherit
* @param {function} origin - 可选,要继承的类
* @param {object} methods - 被创建类的成员,扩展的方法和属性
* @return {KLASS} klass - 继承之后的子类
*/
_.inherit = function(origin, methods) { // 参数检测,该继承方法,只支持一个参数创建类,或者两个参数继承类
if (arguments.length === 0 || arguments.length > 2) throw '参数错误'; var parent = null; // 将参数转换为数组
var properties = slice.call(arguments); // 如果第一个参数为类(function),那么就将之取出
if (typeof properties[0] === 'function') parent = properties.shift();
properties = properties[0]; function klass() {
if (_.isFunction(this.$initialize)) this.$initialize.apply(this, arguments);
} klass.superclass = parent; if (parent) {
// 中间过渡类,防止parent的构造函数被执行
var subclass = function() {};
subclass.prototype = parent.prototype;
klass.prototype = new subclass();
} var ancestor = klass.superclass && klass.superclass.prototype;
for (var k in properties) {
var value = properties[k]; // 满足条件就重写
if (ancestor && typeof value == 'function') {
var argslist = /^\s*function\s*\(([^\(\)]*?)\)\s*?\{/i.exec(value.toString())[1].replace(/\s/g, '').split(',');
// 只有在第一个参数为$super情况下才需要处理(是否具有重复方法需要用户自己决定)
// 第一个参数为super 并且父类存在相同方法的情况下才会执行
if (argslist[0] === '$super' && ancestor[k]) {
value = (function(methodName, fn) {
return function() {
var scope = this;
var args = [function() {
return ancestor[methodName].apply(scope, arguments);
}];
return fn.apply(this, args.concat(slice.call(arguments)));
};
})(k, value);
}
} // 此处对对象进行扩展,当前原型链已经存在该对象,便进行扩展
if (_.isObject(klass.prototype[k]) && _.isObject(value) && (typeof klass.prototype[k] != 'function' && typeof value != 'fuction')) {
// 原型链是共享的,这里处理逻辑要改
var temp = {};
_.extend(temp, klass.prototype[k]);
_.extend(temp, value);
klass.prototype[k] = temp;
} else {
klass.prototype[k] = value;
}
} // 静态属性继承
// 兼容代码,非原型属性也需要进行继承
for (key in parent) {
if (parent.hasOwnProperty(key) && key !== 'prototype' && key !== 'superclass') klass[key] = parent[key];
} if (!klass.prototype.$initialize) klass.prototype.$initialize = function() {}; klass.prototype.constructor = klass;
return klass;
}; })(); //基础方法
(function() {
/**
* seajs.use的包装方法, 直接用seajs.use打包工具会异常
* @method
* @name seaUse
* @param {string} method - 要加载的模块名
* @param {function} callback - 加载完成以后的回调方法
* @return {undefined} undefined - 没有返回值
*/
_.seaUse = function (method, callback) {
var m = 'use';
seajs[m](method, callback);
},
_.removeHTMLTag = function(str) {
if (!str) return;
str = str.replace(/<\/?[^>]*>/g, ''); //去除HTML tag
str = str.replace(/[ | ]*\n/g, '\n'); //去除行尾空白
// str = str.replace(/\n[\s| | ]*\r/g,'\n'); //去除多余空行
str = str.replace(/ /ig, ''); //去掉
return str;
}; // 获取url参数
_.getUrlParam = function(url, key) {
var loc = window.location;
if (!url) url = loc.origin + loc.pathname + loc.search; var searchReg = /([^&=?]+)=([^&]+)/g;
var urlReg = /\/+.*\?/;
var arrayReg = /(.+)\[\]$/;
var urlParams = {};
var match, name, value, isArray; while (match = searchReg.exec(url)) {
name = match[1];
value = match[2];
isArray = name.match(arrayReg);
// 处理参数为url这种情况
if (urlReg.test(value)) {
urlParams[name] = url.substr(url.indexOf(value));
break;
} else {
if (isArray) {
name = isArray[1];
urlParams[name] = urlParams[name] || [];
urlParams[name].push(value);
} else {
urlParams[name] = value;
}
}
} for (var k in urlParams) urlParams[k] = _.removeHTMLTag(decodeURIComponent(urlParams[k])); return key ? urlParams[key] : urlParams;
};
_.fjyGetByteLength = function (str) {
var bytesCount = 0;
for (var i = 0; i < str.length; i++) {
if (/[^\x00-\x80]/g.test(str)) bytesCount += 2;
else bytesCount++;
}
return bytesCount;
};
// 移除空对象
_.removeObjEmpty = function(data) {
var _data = {};
for (var o in data) {
var item = data[o];
if (Object.prototype.toString.call(item) === "[object Object]") {
_data[o] = _.removeObjEmpty(item)
} else {
if (item !== undefined && item !== 'undefined' && item !== null && item !== '') {
_data[o] = item;
}
}
}
return _data
};
_.isWeiXin = function() {
var ua = window.navigator.userAgent.toLowerCase();
if (ua.match(/MicroMessenger/i) == 'micromessenger') {
return true;
} else {
return false;
}
};
_.isQQ = function () {
var ua = navigator.userAgent;
var REGEXP_IOS_QQ = /(iPad|iPhone|iPod).*? (IPad)?QQ\/([\d\.]+)/;
var REGEXP_ANDROID_QQ = /\bV1_AND_SQI?_([\d\.]+)(.*? QQ\/([\d\.]+))?/;
if(REGEXP_IOS_QQ.test(ua) || REGEXP_ANDROID_QQ.test(ua)) {
return true;
} else {
return false;
}
};
// 移除空白符
_.removeAllSpace = function(str) {
if (str) str = str.toString();
else return '';
return str.replace(/\s+/g, "");
}; })(); //日期操作类
(function() { /**
* @description 静态日期操作类,封装系列日期操作方法
* @description 输入时候月份自动减一,输出时候自动加一
* @return {object} 返回操作方法
*/
_.dateUtil = { //根据一个日期获取所有信息
getDetail: function(date) {
if (!date) date = new Date();
var d, now = new Date(),
dateInfo = {},
_diff;
var weekDayArr = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']; if (_.isNumber(date)) {
d = new Date();
d.setTime(date);
date = d;
} //充值date对象,让其成为一天的起点时间
date = new Date(date.getFullYear(), date.getMonth(), date.getDate());
now = new Date(now.getFullYear(), now.getMonth(), now.getDate()); _diff = date.getTime() - now.getTime(); if (_diff == 0) {
dateInfo.day1 = '今天';
} else if (_diff == 86400000) {
dateInfo.day1 = '明天';
} else if (_diff == 172800000) {
dateInfo.day1 = '后天';
} dateInfo.weekday = weekDayArr[date.getDay()]; dateInfo.year = date.getFullYear();
dateInfo.month = date.getMonth() + 1;
dateInfo.day = date.getDate(); return dateInfo; },
/**
* @description 添加n天,
* @param {n} 天数
* @param {date} 默认今天, 支持Date()/timestmap/Y-M-D/Y/M/D 等格式
* @param {formatStr} 默认Y-M-D
* @return {string} 返回处理后的时间对象, 包括时间戳/日期/详情信息
*/
addDay: function (n, date, formatStr) {
var d = date || new Date();
formatStr = formatStr || 'Y-M-D';
if (typeof d === 'string' || typeof d === 'number') {
d = new Date(date);
}
var day = 1000 * 60 * 60 * 24 * n;
var newDay = new Date(d.getTime() + day);
return {
date: newDay,
info: this.getDetail(newDay),
day: this.format(newDay, formatStr)
} },
/**
* @description 数字操作,
* @return {string} 返回处理后的数字
*/
formatNum: function(n) {
if (n < 10) return '0' + n;
return n;
},
/**
* @description 将字符串转换为日期,支持格式y-m-d ymd (y m r)以及标准的
* @return {Date} 返回日期对象
*/
parse: function(dateStr, formatStr) {
if (typeof dateStr === 'undefined') return null;
if (typeof formatStr === 'string') {
var _d = new Date(formatStr);
//首先取得顺序相关字符串
var arrStr = formatStr.replace(/[^ymd]/g, '').split('');
if (!arrStr && arrStr.length != 3) return null; var formatStr = formatStr.replace(/y|m|d/g,
function(k) {
switch (k) {
case 'y':
return '(\\d{4})';
case 'm':
;
case 'd':
return '(\\d{1,2})';
}
}); var reg = new RegExp(formatStr, 'g');
var arr = reg.exec(dateStr) var dateObj = {};
for (var i = 0,
len = arrStr.length; i < len; i++) {
dateObj[arrStr[i]] = arr[i + 1];
}
return new Date(dateObj['y'], dateObj['m'] - 1, dateObj['d']);
}
return null;
},
/**
* @description将日期格式化为字符串
* @return {string} 常用格式化字符串
*/
format: function(date, format) {
if (arguments.length < 2 && !date.getTime) {
format = date;
date = new Date();
}
typeof format != 'string' && (format = 'Y年M月D日 H时F分S秒');
return format.replace(/Y|y|M|m|D|d|H|h|F|f|S|s/g,
function(a) {
switch (a) {
case "y":
return (date.getFullYear() + "").slice(2);
case "Y":
return date.getFullYear();
case "m":
return date.getMonth() + 1;
case "M":
return _.dateUtil.formatNum(date.getMonth() + 1);
case "d":
return date.getDate();
case "D":
return _.dateUtil.formatNum(date.getDate());
case "h":
return date.getHours();
case "H":
return _.dateUtil.formatNum(date.getHours());
case "f":
return date.getMinutes();
case "F":
return _.dateUtil.formatNum(date.getMinutes());
case "s":
return date.getSeconds();
case "S":
return _.dateUtil.formatNum(date.getSeconds());
}
});
},
// @description 是否为为日期对象,该方法可能有坑,使用需要慎重
// @param year {num} 日期对象
// @return {boolean} 返回值
isDate: function(d) {
if ((typeof d == 'object') && (d instanceof Date)) {
return true;
}
return false;
},
// @description 是否为闰年
// @param year {num} 可能是年份或者为一个date时间
// @return {boolean} 返回值
isLeapYear: function(year) {
//传入为时间格式需要处理
if (_.dateUtil.isDate(year)) {
year = year.getFullYear();
}
if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) {
return true;
}
return false;
}, // @description 获取一个月份的天数
// @param year {num} 可能是年份或者为一个date时间
// @param year {num} 月份
// @return {num} 返回天数
getDaysOfMonth: function(year, month) {
//自动减一以便操作
month--;
if (_.dateUtil.isDate(year)) {
month = year.getMonth(); //注意此处月份要加1,所以我们要减一
year = year.getFullYear();
}
return [31, _.dateUtil.isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
}, // @description 获取一个月份1号是星期几,注意此时的月份传入时需要自主减一
// @param year {num} 可能是年份或者为一个date时间
// @param year {num} 月份
// @return {num} 当月一号为星期几0-6
getBeginDayOfMouth: function(year, month) {
//自动减一以便操作
month--;
if ((typeof year == 'object') && (year instanceof Date)) {
month = year.getMonth();
year = year.getFullYear();
}
var d = new Date(year, month, 1);
return d.getDay();
}, //不同时区皆返回北京时间
getBeijingDate: function(d) {
var tmp, localTime, localOffset, beijiTime, utc;
if (!_.isDate(d)) {
tmp = d;
d = new Date();
d.setTime(tmp);
} // 通过调用Data()对象的getTime()方法,即可显示1970年1月1日后到此时时间之间的毫秒数。
localTime = d.getTime();
// 当地时间偏移
localOffset = d.getTimezoneOffset() * 60000;
// 标准时间
utc = localTime + localOffset; // 加上北京偏移量便是北京时区
beijiTime = utc + 28800000; d.setTime(beijiTime);
return d;
}, setBeijingDate: function(d) {
var tmp, localTime, localOffset, beijiTime, utc;
if (!_.isDate(d)) {
tmp = d;
d = new Date();
d.setTime(tmp);
} // 通过调用Data()对象的getTime()方法,即可显示1970年1月1日后到此时时间之间的毫秒数。
localTime = d.getTime();
// 当地时间偏移
localOffset = d.getTimezoneOffset() * 60000;
// 标准时间
utc = localTime - localOffset; //加上北京偏移量便是北京时区
beijiTime = utc - 28800000; d.setTime(beijiTime);
return d;
} }; })(); // Hybrid基本逻辑
(function() {
window.Hybrid = window.Hybrid || {}; var getHybridInfo = function() {
var platform_version = {
platform: 'web',
version: ''
};
var na = navigator.userAgent;
na = na.toLowerCase(); var info = na.match(/tctravel\/\d\.\d\.\d/); if (info && info[0]) {
info = info[0].split('/');
if (info && info.length == 2) {
platform_version.platform = info[0];
platform_version.version = info[1];
}
} else if (_.isWeiXin()) {
platform_version.platform = 'weixin';
platform_version.version = '';
} else if (_.isQQ()) {
platform_version.platform = 'qq';
platform_version.version = '';
} //*debug* 调试模拟环境
if (_.getUrlParam().__platform) {
platform_version.platform = _.getUrlParam().__platform;
platform_version.version = _.getUrlParam().__version;
} return platform_version;
}; var requestHybrid = function(opts) {
var method = opts.method;
method = method.split('.');
if (method.length !== 2) {
throw 'method must be like "_tc_bridge_user.user_login" !';
}
var callbackName = 'HybridCallback_' + _.uniqueId();
var jsonObj = {
param: opts.param,
CBPluginName: 'Hybrid',
CBTagName: callbackName
}
var scope = opts.scope || this;
window.Hybrid[callbackName] = function() {
var args = [].slice.call(arguments);
opts.callback && opts.callback.apply(scope, args);
}
try {
window[method[0]][method[1]](jsonObj);
} catch(e) {
return false;
}
return true;
} var hybridCallback = function(opts) {
var platform = _.getHybridInfo().platform || 'weixin';
var mapping = {
'web': 'web_',
'tctravel': 'tctravel_',
'qq': 'qq_',
'weixin': ''
};
var callbackName = mapping[platform] || '';
// 如果没有定义渠道callback 则默认为普通callback
var callback = opts[callbackName + 'callback'] || opts['callback'];
if (typeof callback == 'function') callback();
};
// 获取cookie
var getCookie = function(name) {
var result = null;
// 对cookie信息进行相应的处理,方便搜索
var myCookie = "" + document.cookie + ";";
var searchName = "" + name + "=";
var startOfCookie = myCookie.indexOf(searchName);
var endOfCookie;
if (startOfCookie != -1) {
startOfCookie += searchName.length;
endOfCookie = myCookie.indexOf(";", startOfCookie);
result = (myCookie.substring(startOfCookie, endOfCookie));
}
return result;
}
// cookie的过期时间, 单位为秒
var setCookie = function (name, value, time) {
var Days = 30;
var exp = new Date();
var time = time ? time * 1000 : Days*24*60*60*1000;
exp.setTime(exp.getTime() + time);
document.cookie = name + "="+ escape (value) + ";expires=" + exp.toGMTString();
}
_.getHybridInfo = getHybridInfo;
_.hybridCallback = hybridCallback;
_.requestHybrid = requestHybrid;
_.getCookie = getCookie;
_.setCookie = setCookie; })();
underscore.extend.js的更多相关文章
- extentreports 测试报告引用extend.js/css失败
测试工程引用extentreports 生成的测试报告,因为报告中的js和css网络不通,所以页面乱码 解决思路: 下载需要的js.css放到测试工程的static目录下 下载extentreport ...
- 【blade利刃出鞘】一起进入移动端webapp开发吧
前言 在移动浪潮袭来的时候,小钗有幸进入框架组做webapp框架开发,过程中遇到了移动端的各种坑,也产生了各种激情,就我们公司的发展历程来说 第一阶段:使用传统方式开发移动站点,少量引入HTML5元素 ...
- 【单页应用】view与model相关梳理
前情回顾 根据之前的学习,我们形成了一个view与一个messageCenterview这块来说又内建了一套mvc的东西,我们这里来理一下首先View一层由三部分组成:① view② dataAdpt ...
- 【单页应用之通信机制】view之间应该如何通信
前言 在单页应用中,view与view之间的通信机制一直是一个重点,因为单页应用的所有操作以及状态管理全部发生在一个页面上 没有很好的组织的话很容易就乱了,就算表面上看起来没有问题,事实上会有各种隐忧 ...
- 【UI插件】简单的日历插件(下)—— 学习MVC思想
前言 我们上次写了一个简单的日历插件,但是只是一个半成品,而且做完后发现一些问题,于是我们今天尝试来解决这些问题 PS:距离上次貌似很久了 上次,我们大概遇到哪些问题呢: ① 既然想做一套UI库,那么 ...
- 【单页应用】view与model相关梳理(转载)
[单页应用]view与model相关梳理 前情回顾 根据之前的学习,我们形成了一个view与一个messageCenterview这块来说又内建了一套mvc的东西,我们这里来理一下首先View一层由三 ...
- underscore.js学习笔记
一.理清概念 1.Underscore封装了常用的JavaScript对象操作方法,用于提高开发效率,Underscore还可以被使用在Node.js运行环境.从API中,你已经可以看出,Unders ...
- underscore.js库的浅析
Underscore并没有在原生的JavaScript对象原型中进行扩展,而是像jQuery一样,将数据封装在一个自定义对象中(下文称“Underscore对象”).生成一个Underscore对象: ...
- (1)Underscore.js入门
1. Underscore对象封装 Underscore并没有在原生的JavaScript对象原型中进行扩展,而是像jQuery一样,将数据封装在一个自定义对象中(下文中称"Undersco ...
随机推荐
- 重写equals方法
用下面的例子来进行解释. String name; int id; @Override public boolean equals(Object otherObject) { if (this == ...
- android 指示器 tablatyout
<android.support.design.widget.TabLayout/>android 材料设计中新出的控件 package com.weavey.loadinglayout; ...
- SDWebImage下载图片有时候无法成功显示出来
之前用下面的方法现在图片,有时候会出现图片没有下载成功显示: - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)p ...
- Dapper学习笔记(4)-事务
Dapper中对事务的处理也非常简单,如下代码所示: private void DapperTransaction() { using (IDbConnection con = OpenConnect ...
- 点击按钮跳出隐藏的div层,并设背景。
style: .black_overlay{ display: none; position: absolute; top: 0%; left: 0%; width: 100%; height: 10 ...
- JAVA中管道通讯(线程间通讯)例子
Java I/O系统是建立在数据流概念之上的,而在UNIX/Linux中有一个类似的概念,就是管道,它具有将一个程序的输出当作另一个程序的输入的能力.在Java中,可以使用管道流进行线程之间的通信,输 ...
- JAVA String,StringBuffer与StringBuilder的区别??
String 字符串常量StringBuffer 字符串变量(线程安全)StringBuilder 字符串变量(非线程安全) 简要的说, String 类型和 StringBuffer 类型的主要性能 ...
- 用springMVC构建restful程序,接收以及返回json数据格式
主要参考文章:http://kingxss.iteye.com/blog/1487745和http://blog.csdn.net/greensurfer/article/details/192962 ...
- visualssh 是一个可视化的ssh客户端
这两个周末写了visualssh,一个可视化的ssh客户端.里面集成了putty的功能,通过ssh协议与Linux server通讯. 以后可以针对不同的应用编写相关插件,便于管理Linux服务器上的 ...
- 运行带cocoa pods 的项目,遇到的问题是找不到文件,解决办法
打开终端,进入项目所在的目录,也就是和Podfile在同一目录下,输入以下命令(由于已经有Podfile,所以不需要再创建Podfile): pod update 过几秒(也许需要十几秒,取决于你的 ...