/*
* @Author: chenyaoyi
* @Date: 2017-12-25 11:41:11
* @Last Modified by: chenyaoyi
* @Last Modified time: 2018-01-04 10:07:56
*/
///
/**
* DOM 元素全部加载完成
* @param fn 成功回调
*/
function domReady(fn: Function): void {
if (document.addEventListener) {
document.addEventListener('DOMContentLoaded', function () {
fn && fn();
}, false);
} else {
document['attachEvent']('onreadystatechange', function () {
if (document.readyState == 'complete') {
fn && fn();
}
});
}
}
/**
* 确保页面中 js/css 完全加载
*
* @param url url
* @param fnSucc 加载之后的回调函数
*/
function loadFile(url: string, fnSucc: Function): any {
const type: string = getFileType(url);
if (type === 'unknow') return type;
const oTag: HTMLScriptElement | HTMLLinkElement | any = document.createElement(type);
switch (type) {
case 'js':
oTag.src = url;
break;
case 'css':
oTag.rel = 'stylesheet';
oTag.href = url;
break;
}
const oHead: HTMLHeadElement = document.getElementsByTagName('head')[0];
oHead.appendChild(oTag);
oTag.onload = oTag.onreadystatechange = function () {
if (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete') {
fnSucc && fnSucc();
}
};
}
/**
* url 上面获取参数对应的值
*
* @param name 要截的值名称
*/
function getQueryString(name: string): string | null {
const reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)');
const r = window.location.search.substr(1).match(reg);
if (r != null) {
return window['unescape'](r[2]);
};
return null;
}
/**
* 返回一个在特点范围内的随机数字
*
* @param startNum 开始
* @param endNum 结束
*/
function getRandomNum(startNum: number, endNum: number) {
return parseInt(String(Math.random() * (endNum + 1 - startNum) + startNum));
}
/**
* 获取文件类型
* @param file 文件对象
*/
function getFileType(file: string): string {
const cuttingPoint = file.lastIndexOf('.');
if (cuttingPoint == -1) {
return 'unknow';
} else {
return file.substring(cuttingPoint + 1);
}
}
/**
* 鼠标滚轮事件
* @param obj 响应鼠标滚轮的元素
* @param fn 鼠标滚轮后的回调函数
*/
function fnMouseWheel(obj: HTMLElement, fn: Function): void {
if (window.navigator.userAgent.toLowerCase().indexOf('firefox') != -1) {
obj.addEventListener('DOMMouseScroll', fnWheel, false);
} else {
obj.onmousewheel = fnWheel;
}
/**
* 鼠标滚轮事件
* @param ev 事件对象
*/
function fnWheel(ev: Event): boolean {
const oEvent: any = ev || window.event;
let bDown = true;
if (oEvent.wheelDelta) {
bDown = oEvent.wheelDelta > 0 ? false : true;
} else {
bDown = oEvent.detail > 0 ? true : false;
}
fn && fn(bDown);
oEvent.preventDefault && oEvent.preventDefault();
return false;
}
}
/**
* 判断对象是否为空,true -> json为空
* @param json json 对象
*/
function isJsonEmpty(json: Object): boolean {
for (let name in json) {
// 如果 json 有数据则会进入循环
return false;
}
return true;
}
function isArray(obj): boolean {
return Object.prototype.toString.call(obj) === '[object Array]';
}
/**
* 操控样式
*/
const fnClass = {
/**
* 样式是否存在
* @param obj HTML元素
* @param sClass 样式名
*/
hasClass: function (obj: HTMLElement, sClass: string): boolean {
if (obj.classList.contains) {
return obj.classList.contains(sClass);
} else {
const reg = new RegExp('\\b' + sClass + '\\b');
return reg.test(obj.className);
}
},
/**
* 添加样式
* @param obj HTML元素
* @param sClass 样式名
*/
addClass: function (obj: HTMLElement, sClass: string): Object {
if (obj.className) {
if (!this.hasClass(obj, sClass)) {
if (obj.classList.add) {
obj.classList.add(sClass);
} else {
obj.className += ' ' + sClass;
}
}
} else {
obj.className = sClass;
}
return obj;
},
/**
* 移除样式
* @param obj HTML元素
* @param sClass 样式名
*/
removeClass: function (obj: HTMLElement, sClass: string): Object {
if (obj.classList.remove) {
obj.classList.remove(sClass);
} else {
const reg = new RegExp('\\b' + sClass + '\\b');
if (this.hasClass(obj, sClass)) {
obj.className = obj.className.replace(reg, '').replace(/^\s+|\s+$/g, '').replace(/\s+/g, '');
}
}
return obj;
}
};
/**
* 设置 css3 的样式
* @param obj HTML元素
* @param name 要设置的样式名称
* @param value 要设置的样式值
*/
function setCss3Style(obj: HTMLElement, name: string, value: string): void {
const str = name.charAt(0).toUpperCase() + name.substring(1);
obj.style['Webkit' + str] = value;
obj.style['Moz' + str] = value;
obj.style['ms' + str] = value;
obj.style['O' + str] = value;
obj.style[name] = value;
};
/**
* 倒计时
*
* @param options 参数对象
*
*/
function setCountdown(options: Countdown) {
this.options = options || {};
this.timer = null;
this.newTimeSecond = null;
this.showTimeElement = null;
this.sDay = '';
this.sHour = '';
this.sMin = '';
this.sSec = '';
// 初始化设置
this.init = function (): void {
this.options.serverTimestamp = options.serverTimestamp || new Date().getTime();
this.options.startTimestamp = options.startTimestamp || 0;
this.options.showTimeElement = options.showTimeElement || '';
this.options.showTimeSymbol = options.showTimeSymbol || {};
this.sDay = this.options.showTimeSymbol.day;
this.sHour = this.options.showTimeSymbol.hour;
this.sMin = this.options.showTimeSymbol.min;
this.sSec = this.options.showTimeSymbol.sec;
// 如果没有活动开始时间,则退出
if (!/^\d{13}$/.test(this.options.startTimestamp)) {
return;
}
// 如果填写了 html 元素,则显示在该 html 元素上
if (this.options.showTimeElement) {
const oShowTimeElement = document.querySelectorAll(this.options.showTimeElement);
if (oShowTimeElement && oShowTimeElement.length) {
this.showTimeElement = oShowTimeElement;
}
}
// 将获取到的服务器时间转换为秒(方便计算)
this.newTimeSecond = parseInt(String(new Date(this.options.serverTimestamp).getTime() / 1000));
// 设置时间
this.setTime();
};
// 设置时间
this.setTime = function () {
const _this = this;
const oServerTime = new Date(this.options.serverTimestamp);
const oStartTime = new Date(this.options.startTimestamp);
const oYear = oStartTime.getFullYear();
const oMonth = oStartTime.getMonth() + 1;
const oDay = oStartTime.getDay();
const oHour = oStartTime.getHours();
const oMin = oStartTime.getMinutes();
const oSec = oStartTime.getSeconds();
// 设置活动开始时间:年月日时分秒
oServerTime.setFullYear(oYear, oMonth, oDay);
oServerTime.setHours(oHour, oMin, oSec);
// 时间换算,先立即执行一次
this.timeRun(oStartTime);
// 不断使用定时器执行
this.timer = setInterval(function () {
_this.timeRun(oStartTime);
}, 1000);
};
// 时间换算
this.timeRun = function (oStartTime) {
// 秒数++,每一秒,秒数+1,代表从服务器时间获取到的时间基础上继续跑
this.newTimeSecond++;
// 算出新的时间差
let x = parseInt(String((oStartTime.getTime() - new Date(this.newTimeSecond * 1000).getTime()) / 1000));
// 剩余天数
const d = parseInt(String(x / 86400));
x %= 86400;
// 剩余小时数
const h = parseInt(String(x / 3600));
x %= 3600;
// 剩余分钟数
const m = parseInt(String(x / 60));
// 剩余秒数
x %= 60;
// 将换算好的时间通过回调函数抛出去,如果需要自定义显示格式,可以从这个回调函数中获取时间
this.options.showtime && this.options.showtime({
day: this.addZero(d),
hour: this.addZero(h),
min: this.addZero(m),
sec: this.addZero(x)
});
// 如果填写了 html 元素,而且自定义了 天/时/分/秒 的格式,则按照自定义的格式显示在该 html 元素上
if (this.showTimeElement && this.showTimeElement.length) {
for (let i = 0; i < this.showTimeElement.length; i++) {
let sShowTime = '';
const sDay = this.sDay ? this.addZero(d) + this.sDay : '';
const sHour = this.sHour ? this.addZero(h) + this.sHour : '';
const sMin = this.sMin ? this.addZero(m) + this.sMin : '';
const sSec = this.sSec ? this.addZero(x) + this.sSec : '';
sShowTime = sDay + sHour + sMin + sSec;
this.showTimeElement[i] && (this.showTimeElement[i].innerHTML = sShowTime);
}
}
// 判断时间是否倒数结束
if (d === 0 && h === 0 && m === 0 && x === 0) {
// 时间到,停止倒计时
clearInterval(this.timer);
if (this.showTimeElement && this.showTimeElement.length) {
for (let i = 0; i < this.showTimeElement.length; i++) {
this.showTimeElement[i] && (this.showTimeElement[i].innerHTML = '00:00:00');
}
}
this.options.timeup && this.options.timeup();
}
};
// 单位数字,前面补0
this.addZero = function (num: any): string | number {
if (num === 'undefined' || num === undefined || num === '' || num === null) {
return '';
};
const newNum = typeof num === 'number' ? num : parseInt(num);
return newNum > 9 ? newNum : ('0' + newNum);
};
this.init();
}
/**
* 字符串间隔(字符串四位间隔)
*
* @param {string} type 类型 phone: 手机,bankcard: 银行卡
* @param {string} val 要转换的字符串
* @returns {string} 返回处理完的字符串
*/
function setStringSpacing(type: string, val: string): string {
val = val.replace(/\s/g, '').replace(/(.{4})/g, '$1 ');
if (type === 'bankcard') {
val = val.replace(/\s/g, '').replace(/(.{4})/g, '$1 ');
} else if (type === 'phone') {
if (val.length < 3) {
val = val.replace(/\s/g, '');
} else {
val = val.substring(0, 3) + ' ' + val.substring(3).replace(/\s/g, '').replace(/(.{4})/g, '$1 ');
}
}
if (val.charAt(val.length - 1) === ' ') {
val = val.substring(0, val.length - 1);
}
return val;
}
/**
* 时间格式转换
*
* @param {(string | number)} time 时间戳
* @param {string} [symbol='.'] 间隔符号
* @returns {string} YYYY.MM.DD hh:mm:ss
*/
function formatDate(time: string | number, symbol: string = '.'): string {
if (time) {
const newTime = typeof time === 'number' ? time : parseInt(time);
const date = new Date(newTime);
return date.getFullYear() + symbol + formatSingleNum(date.getMonth() + 1) + symbol + formatSingleNum(date.getDate()) +
' ' + formatSingleNum(date.getHours()) + ':' + formatSingleNum(date.getMinutes()) + ':' + formatSingleNum(date.getSeconds());
} else {
return '----.--.-- --:--:--';
}
}
/**
* 将小于10的数字前面加上'0'
*
* @param {*} num
* @returns {(string | number)}
*/
function formatSingleNum(num: any): string | number {
if (num === 'undefined' || num === undefined || num === '' || num === null) return;
const newNum = typeof num === 'number' ? num : parseInt(num);
return newNum > 9 ? newNum : ('0' + newNum);
}
/**
* 字符串截取(多余的显示省略号)
*
* @param {string} value 要截取的字符串
* @param {number} [len=10] 截取的长度
* @returns {string} 返回处理完的字符串
*/
function stringCut(value: string, len: number = 10): string {
const v: string = String(value);
if (v) {
if (v.length === 0) {
return '';
} else if (v.length < len) {
return v;
} else {
const arr = v.split('');
arr.length = len;
return arr.join('') + '...';
}
} else {
return v;
}
}
/**
* 数值添加千分位处理
*
* @param {*} num 需要处理的字符串或数字
* @returns {string} 返回处理完的字符串
*
*/
function formatThousands(num: any): string {
// 1.先去除空格,判断是否空值和非数
num = num + '';
// 去除空格
num = num.replace(/[ ]/g, '');
if (!/\d/.test(num) || isNaN(num)) {
return null;
};
// 2.针对是否有小数点,分情况处理
const index: number = num.indexOf('.');
if (index === -1) {
// 无小数点
const reg: RegExp = /(-?\d+)(\d{3})/;
while (reg.test(num)) {
num = num.replace(reg, '$1,$2');
}
num += '.00';
} else {
let intPart: string = num.substring(0, index);
const pointPart: string = num.substring(index + 1, num.length);
const reg: RegExp = /(-?\d+)(\d{3})/;
while (reg.test(intPart)) {
intPart = intPart.replace(reg, '$1,$2');
}
num = intPart + '.' + pointPart;
}
return num;
}
/**
* 判断浏览器
*/
const fnBrowser = {
ua: window.navigator.userAgent.toLowerCase(),
/**
* 判断是移动端还是PC端
*/
isMobile: function () {
return this.ua.match(/mobile/i);
},
/**
* 判断是否微信
*/
isWeixin: function (): boolean {
if (this.ua.match(/MicroMessenger/i) && this.ua.match(/MicroMessenger/i).length > 0) {
return true;
} else {
return false;
}
},
/**
* 判断是否 ios 设备
*/
isIOS: function () {
return this.ua.match(/iPad/i) || this.ua.match(/iPhone/i) || this.ua.match(/iPod/i);
},
/**
* 判断是否 android 设备
*/
isAndroid: function () {
return this.ua.match(/Android/i);
},
/**
* 判断是否 webview
*/
isWebView: function () { }
};
/**
* json 转成 url
*
* @param json json对象
*/
function jsonTourl(json: { t: number }): string {
json.t = Math.random();
let arr = [];
for (let name in json) {
arr.push(name + '=' + encodeURIComponent(json[name]));
}
return arr.join('&');
}
/**
* HTTP 请求
*/
const http = {
get: function (url: string, params: any = {}, options?: Ajax_Options): Promise {
const xhr = new XMLHttpRequest();
let timer = null;
if (options && options.headers) {
for (let pro in options.headers) {
xhr.setRequestHeader(pro, options.headers[pro]);
};
}
xhr.open('GET', url + '?' + jsonTourl(params), true);
xhr.send();
return this.hanlde(xhr, timer, options);
},
post: function (url: string, params: any = {}, options?: Ajax_Options): Promise {
const xhr = new XMLHttpRequest();
let timer = null;
if (options && options.headers) {
for (let pro in options.headers) {
xhr.setRequestHeader(pro, options.headers[pro]);
};
}
xhr.open('POST', url, true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
if (typeof params === 'string') {
xhr.send(params);
} else {
xhr.send(jsonTourl(params));
}
return this.hanlde(xhr, timer, options);
},
hanlde: function (xhr: XMLHttpRequest, timer: any, options?: Ajax_Options) {
return new Promise((resolve, reject) => {
xhr.onreadystatechange = function () {
// 完成
if (xhr.readyState === 4) {
clearTimeout(timer);
if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
resolve(JSON.parse(xhr.responseText));
} else {
// 失败
reject('error');
}
}
};
if (options && options.timeout) {
timer = setTimeout(function () {
reject('timeout');
// 终止
xhr.abort();
}, options.timeout);
}
});
}
};
export {
domReady,
loadFile,
getFileType,
getQueryString,
getRandomNum,
fnMouseWheel,
isJsonEmpty,
isArray,
fnClass,
fnBrowser,
setCss3Style,
setCountdown,
setStringSpacing,
formatDate,
formatSingleNum,
formatThousands,
stringCut,
jsonTourl,
http
};