整理收集的JavaScript工具类与方法合集,其实有不少工具类开源项目已经实现了不少,开箱即用。常见工具类如下:
工具类
时间相关库
- Day.js Day.js 是一个轻量级的 JavaScript 日期和时间处理库,它提供了简洁易用的 API,用于解析、操作和格式化日期和时间。
地理信息
- Turf.js Turf 是一个用于地理空间分析和操作的 JavaScript 库。它提供了许多方便的函数和工具,用于处理地理数据、执行地理空间计算和分析以及创建交互式地图应用程序。
展示相关
- cleave-zen 数字格式化,比如信用卡,时间,电话号码等等
- reveal.js HTML演示文稿框架。
防抖debounce
代码
javascript
function debounce(func, wait, immediate) {
var timeout, result;
var debounced = function () {
var context = this;
var args = arguments;
if (timeout) clearTimeout(timeout);
if (immediate) {
// 如果已经执行过,不再执行
var callNow = !timeout;
timeout = setTimeout(function(){
timeout = null;
}, wait)
if (callNow) result = func.apply(context, args)
}
else {
timeout = setTimeout(function(){
func.apply(context, args)
}, wait);
}
return result;
};
debounced.cancel = function() {
clearTimeout(timeout);
timeout = null;
};
return debounced;
}
使用
javascript
function getUserAction(e) {
...
};
// 防抖
var setUseAction = debounce(getUserAction, 10000, true);
// 取消
setUseAction.cancel();
节流throttle
代码
javascript
function throttle(func, wait, options) {
var timeout, context, args, result;
var previous = 0;
if (!options) options = {};
var later = function() {
previous = options.leading === false ? 0 : new Date().getTime();
timeout = null;
func.apply(context, args);
if (!timeout) context = args = null;
};
var throttled = function() {
var now = new Date().getTime();
if (!previous && options.leading === false) previous = now;
var remaining = wait - (now - previous);
context = this;
args = arguments;
if (remaining <= 0 || remaining > wait) {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
previous = now;
func.apply(context, args);
if (!timeout) context = args = null;
} else if (!timeout && options.trailing !== false) {
timeout = setTimeout(later, remaining);
}
};
throttled.cancel = function() {
clearTimeout(timeout);
previous = 0;
timeout = null;
};
动态加载第三方JS
代码
javascript
function loadScript(src, callback) {
var script = document.createElement('script'),
head = document.getElementsByTagName('head')[0];
script.type = 'text/javascript';
script.charset = 'UTF-8';
script.src = src;
if (script.addEventListener) {
script.addEventListener('load', function () {
callback();
}, false);
} else if (script.attachEvent) {
script.attachEvent('onreadystatechange', function () {
var target = window.event.srcElement;
if (target.readyState == 'loaded') {
callback();
}
});
}
head.appendChild(script);
}
使用
javascript
loadScript('https://cdn.bootcss.com/Turf.js/5.1.6/turf.min.js',function(){
console.log('onload');
console.log(turf);
});
获取当前JS路径
js
function getPath() {
let jsPath = document.currentScript ? document.currentScript.src : function () {
let js = document.scripts
, last = js.length - 1
, src;
for (let i = last; i > 0; i--) {
if (js[i].readyState === 'interactive') {
src = js[i].src;
break;
}
}
return src || js[last].src;
}();
return jsPath.substring(0, jsPath.lastIndexOf('/') + 1);
}
alert(getPath());
随机整数
js
var min = 5;
var max = 10;
var rand = Math.floor(Math.random()*(max-min+1))+min;
时间格式化
js
Date.prototype.Format = function(fmt) { //author: meizz
var o = {
"M+": this.getMonth() + 1, //月份
"d+": this.getDate(), //日
"h+": this.getHours(), //小时
"m+": this.getMinutes(), //分
"s+": this.getSeconds(), //秒
"q+": Math.floor((this.getMonth() + 3) / 3), //季度
"S": this.getMilliseconds() //毫秒
};
if (/(y+)/.test(fmt))
fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
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;
}
JSON结构数据转树结构
代码
javascript
function transData(a, idStr, pidStr, chindrenStr) {
var r = [], hash = {}, id = idStr, pid = pidStr, children = chindrenStr, i = 0, j = 0, len = a.length;
for (; i < len; i++) {
hash[a[i][id]] = a[i];
}
for (; j < len; j++) {
var aVal = a[j], hashVP = hash[aVal[pid]];
if (hashVP) {
!hashVP[children] && (hashVP[children] = []);
hashVP[children].push(aVal);
} else {
r.push(aVal);
}
}
return r;
}
使用
javascript
function test() {
//json串
var jsonData = eval('[{"belongsname":"","id":901,"isleaf":0,"name":"XJBHX-2标项目部","pid":"","type":""},{"belongsname":"","id":902,"isleaf":1,"name":"综合部(办公室)","pid":"901","type":""},{"belongsname":"","id":903,"isleaf":1,"name":"工程部(工技部/技术部)","pid":"901","type":""},{"belongsname":"","id":904,"isleaf":1,"name":"安质部","pid":"901","type":""},{"belongsname":"","id":905,"isleaf":1,"name":"计财部","pid":"901","type":""},{"belongsname":"","id":906,"isleaf":1,"name":"物设部(物机部)","pid":"901","type":""},{"belongsname":"","id":907,"isleaf":1,"name":"中心试验室","pid":"901","type":""}]');
//绑定的字段
var jsonDataTree = transData(jsonData, 'id', 'pid', 'chindren');
console.log(jsonDataTree);
}
千分位
方法一:倒序遍历
js
function qianfenwei(num) {
// 0. 将数字转成字符
num += '';
let result = '';
// 1.倒序遍历
num = num.split('').reverse();
num.forEach((v, i) => {
// 2.遍历时,后遍历的数需放入先遍历的数前面
result = v + result;
// 3.每隔3位加一个逗号
if (i % 3 === 2 && i !== num.length - 1) {
result = ',' + result;
}
});
console.log(result);
return result;
}
方法二:分开处理
js
// 将数字分为长度是3倍数的部分和剩余部分
function qianfenwei2(num) {
const len = num.length;
// 获取剩余长度
const remainderLen = len % 3;
// 取出剩余字符串
const result = remainderLen ? [num.substring(0, remainderLen)] : [];
// 对其余长度是3的倍数的字符做遍历
for (let i = remainderLen; i < len; i += 3) {
result.push(num.substring(i, i + 3));
}
console.log(result.join(','));
return result.join(',');
}
方法三:正则表达式
js
function qianfenwei3(num) {
// 正则1:
// const len = num.length;
// 将字符填充为长度是3倍速的字符,在数字最前面填充0
// const splitCount = Math.ceil(len / 3);
// num = num.padStart(splitCount * 3, '0');
// 每遇到三个数字就多加一个逗号
// let result = num.replace(/(\d{3})/g,'$1,');
// 将结果最前面的0及最末尾的逗号都替换为空
// result = result.replace(/^0/g, '').replace(/,$/,'');
// 正则2:
// 替换后面是一个或多个3个数字且不是开头位置的地方为,
const result = num.replace(/(?<!^)(?=(\d{3})+$)/g, ',');
console.log(result);
return result;
}
localStorage同页面监听
js
var oriSetItem = localStorage.setItem;
localStorage.setItem = function (key, value) {
//这里抛出自定义事件
var event = new Event("setItemEvent");
event.newValue = value;
window.dispatchEvent(event);
//实现原方法
oriSetItem.apply(this, arguments);
}
然后就能在当前页监听 setItemEvent 啦。window.addEventListener("setItemEvent", function (e) {
console.log("本地存储已变化,新值为" + e.newValue);
});
深copy
javascript
function deepCopy(obj) {
if (obj === null || typeof obj !== 'object') {
return obj;
}
if (Array.isArray(obj)) {
const arrCopy = [];
for (let i = 0; i < obj.length; i++) {
arrCopy[i] = deepCopy(obj[i]);
}
return arrCopy;
}
const objCopy = {};
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
objCopy[key] = deepCopy(obj[key]);
}
}
return objCopy;
}
// 示例
js
const original = {
a: 1,
b: {
c: 2,
d: [3, 4]
}
};
const copied = deepCopy(original);
console.log(copied);
console.log(original === copied); // false
console.log(original.b === copied.b); // false