通用类
对象数组路径查找
/**
* Object takes value by path
* @function get
* @param {Record<string, any> | any[]} source
* @param {String} path 指定的查询路径,支持.操作符,支持数组下标[i]
* @param {any} defaultValue 返回的默认值, 非必传
* @returns
* @demo
* let obj = {a: 'aaa', b: { c: 'ccc', d: ['d1', 'd2']}};
* let val = XTakeAt.getValue(obj, 'b.d[0]', )
* 返回 => 'd1'
*/
function takeAt(source, path, defaultValue = undefined) {
let target = source;
let handlePath = path;
// 如果是数字则转换为字符串
if (isNum(path)) handlePath = isNaN(path) ? '' : path.toString();
// 如果路径不是字符串则返回默认值
if (isStr(handlePath)) return defaultValue;
// 判断是不是对象或数组,如果都不是就返回目标对象
if (!isObj(source) && !isArr(source)) return source;
// 将路径格式转数组
const routes = handlePath.replace(/(\[|\])/g, a => (a === '[' ? '.' : '')).split('.');
// 返回取得的结果
for (let i = 0, len = routes.length; i < len; i++) {
const field = routes[i];
if (XAssert.isUndef(target[field])) return (target = defaultValue);
target = target[field];
}
return target;
};
长度方法
function len(source: string | any[] | Record<string, any> | Map<any, any> | Set<any>): number {
if (typeof source === 'string') return source.length;
if (Array.isArray(source)) return source.length;
if (Object.prototype.toString.call(source).slice(8, -1) === 'Object') return Object.keys(source).length;
if (['Map', 'Set'].includes(Object.prototype.toString.call(source).slice(8, -1))) return source.size;
throw new TypeError('Incorrect type, should be string, array, object, Map object, Set object');
}
动态加载JS文件1
function loadJS(files, done) {
// 获取head标签
const head = document.getElementsByTagName('head')[0];
Promise.all(files.map(file => {
return new Promise(resolve => {
// 创建script标签并添加到head
const s = document.createElement('script');
s.type = "text/javascript";
s.async = true;
s.src = file;
// 监听load事件,如果加载完成则resolve
s.addEventListener('load', (e) => resolve(), false);
head.appendChild(s);
});
})).then(done); // 所有均完成,执行用户的回调事件
}
loadJS(["test1.js", "test2.js"], () => {
// 用户的回调逻辑
});
动态加载JS文件2
/**
*
* @param {string} id
* @param {string} url
* @param {(status: boolean, message: { status: 'fail' | 'success', message: string }) => void} callback
* @returns {void | Promise<{ status: 'fail' | 'success', message: string }>}
* @throws
*/
function addScript(id, src, callback = void 0) {
// 支持 promise 返回取得的结果
let promise;
if (!isFunc(success) && window && window.Promise) {
promise = new window.Promise((resolve, reject) => {
callback = function (status, message) {
status ? resolve(message) : reject(message);
};
});
}
// 判断必传值
if (isUndef(id)) callback(false, { status: 'fail', message: 'missing field "id" parameter' });
if (isUndef(src)) callback(false, { status: 'fail', message: 'missing field "src" parameter' });
// 判断浏览器环境
if (window && window.document) {
// 是否存在
const isExisting = document.getElementById(id);
// 判断浏览器环境防止重复加载如果存在就返回警告 但是返回成功状态
if (!isExisting) {
const script = document.createElement('script');
script.src = src;
script.id = id;
document.body.appendChild(script);
'onload' in script ? renderBrower(script) : renderIEBrower(script);
} else {
callback(true, { status: 'warn', message: 'script already exists' });
}
} else {
callback(false, { status: 'fail', message: 'The current window does not contain a window object' });
}
// IE 加载
function renderIEBrower(script) {
script.onreadystatechange = function () {
if (this.readyState !== 'complete' && this.readyState !== 'loaded') return void 0;
this.onreadystatechange = null;
callback(true, { status: 'success', message: 'success loaded' });
};
}
// 其他浏览器 加载
function renderBrower(script) {
// 成功
script.onload = function () {
this.onerror = this.onload = null;
callback(true, { status: 'success', message: 'success loaded' });
};
// 失败
script.onerror = function () {
this.onerror = this.onload = null;
callback(false, { status: 'fail', message: 'Failed to load ' + src, id: id });
};
}
if (promise) return promise;
};
链接获取参数
单个字段1
const getUrlParam = (key) => {
const url = new URL(window.location.href);
const value = url.searchParams.get(key);
return value;
};
getUrlParam("id");
单个字段2
// 浏览器
function getUrlParam(name:string) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
var result = window.location.search.substr(1).match(reg);
return result ? decodeURIComponent(result[2]) : null;
}
// 小程序 name:查询字段,q链接地址
function getUrlParam(name: string, q: string) {
const reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)');
const qstr = decodeURIComponent(q).split('?')[1];
const result = qstr.substring(0).match(reg);
return result ? result[2] : '';
}
多个字段
// 直接获取
function getUrlParams() {
var url = window.location.search; //获取url中"?"符后的字串
var temp = new Object();
if(url.indexOf("?") != -1) {
var str = url.substr(1);
strs = str.split("&");
for(var i = 0; i < strs.length; i++) {
temp[strs[i].split("=")[0]] = (strs[i].split("=")[1]);
}
}
return temp;
}
// 传入url
function getUrlParams(url) {
if (!url) return;
const paramStr = url.match(/.*\?([-\w+&@#/%?=~_|!:,.;]*)/i)?.[1];
if (!paramStr) return;
const split = decodeURIComponent(paramStr).split('&');
return result = split.reduce((prev, curr) => {
const [key, value] = curr.split('=');
prev[key] = value;
return prev;
}, {});
}
是否在浏览器
用于判断程序运行环境是否在浏览器,这有助于避免在node环境运行前端模块时出错。
const isBrowser = () => ![typeof window, typeof document].includes('undefined');
isBrowser(); // true (browser)
isBrowser(); // false (Node)
PC 类
全屏切换
function tooggleFullScreen(isFullscreen) {
isFullscreen = isFullscreen === undefined ? !(document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen) : isFullscreen
var de = document.documentElement
if (isFullscreen) { // 进入全屏
if (de.requestFullscreen) {
de.requestFullscreen()
} else if (de.mozRequestFullScreen) {
de.mozRequestFullScreen()
} else if (de.webkitRequestFullScreen) {
de.webkitRequestFullScreen()
}
} else { // 退出全屏
de = document
if (de.exitFullscreen) {
de.exitFullscreen()
} else if (de.mozCancelFullScreen) {
de.mozCancelFullScreen()
} else if (de.webkitExitFullscreen) {
de.webkitExitFullscreen()
}
}
}
回到顶部
const scrollToTop = () => {
const c = document.documentElement.scrollTop || document.body.scrollTop;
if (c > 0) {
window.requestAnimationFrame(scrollToTop);
window.scrollTo(0, c - c / 8);
}
};
scrollToTop();
复制文本
const copyText = (text) => {
const clipboardData = window.clipboardData;
if (clipboardData) {
clipboardData.clearData();
clipboardData.setData("Text", text);
return true;
} else if (document.execCommand) {
const el = document.createElement("textarea");
el.value = text;
el.setAttribute("readonly", "");
el.style.position = "absolute";
el.style.left = "-9999px";
document.body.appendChild(el);
el.select();
document.execCommand("copy");
document.body.removeChild(el);
return true;
}
return false;
};
copyText("Test");
复制文本带版权信息
document.body.oncopy = (event) => {
event.preventDefault();
const clipboardData = event.clipboardData;
let text = window.getSelection(0).toString();
text = `${text}\n这是插入的文本\n 作者:于五五\n`;
if (clipboardData) {
clipboardData.clearData();
clipboardData.setData("Text", text);
return true;
} else if (document.execCommand) {
window.clipboardData.setData("Text", text);
}
return false;
};
禁止某些操作
// 禁止右键菜单
document.body.oncontextmenu = (e) => {
return false;
};
// 禁止选中文字
document.body.onselectstart = (e) => {
return false;
};
// 禁止复制
document.body.oncopy = (e) => {
return false;
};
// 禁止剪切
document.body.oncut = (e) => {
return false;
};
// 禁止粘贴
document.body.onpaste = (e) => {
return false;
};
标签页显隐
对标签页显示隐藏进行事件监听时
const {hidden, visibilityChange} = (() => {
let hidden, visibilityChange;
if (typeof document.hidden !== "undefined") {
// Opera 12.10 and Firefox 18 and later support
hidden = "hidden";
visibilityChange = "visibilitychange";
} else if (typeof document.msHidden !== "undefined") {
hidden = "msHidden";
visibilityChange = "msvisibilitychange";
} else if (typeof document.webkitHidden !== "undefined") {
hidden = "webkitHidden";
visibilityChange = "webkitvisibilitychange";
}
return {
hidden,
visibilityChange
}
})();
const handleVisibilityChange = () => {
console.log("当前被隐藏", document[hidden]);
};
document.addEventListener(
visibilityChange,
handleVisibilityChange,
false
);
页面是否滚动到页面底部
用于检测页面是否滚动到页面底部。
const bottomVisible = () =>
document.documentElement.clientHeight + window.scrollY >=
(document.documentElement.scrollHeight || document.documentElement.clientHeight);
bottomVisible(); // true
判断当前页面是否处于活动状态
用于判断当前页面是否处于活动状态(显示状态)。
const isBrowserTabFocused = () => !document.hidden;
isBrowserTabFocused(); // true
移动端类
ua 环境判断
const getUaInfo = () => {
const ua = navigator.userAgent.toLowerCase();
const Agents = [
"Android",
"android",
"iPhone",
"SymbianOS",
"Windows Phone",
"iPad",
"iPod",
];
let isPc = true;
for (var i = 0; i < Agents.length; i++) {
if (userAgentInfo.includes(Agents[i])) {
isPc = false;
break;
}
}
return {
// 是不是ios
isIos:
!!ua.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/) || ua.includes("mac os x"),
// 是不是安卓
isAndroid:
ua.includes("android") || ua.includes("Android") || ua.includes("Adr"),
// 是不是微信环境
isWeixin: ua.match(/MicroMessenger/i) == "micromessenger",
// 是不是电脑端
isPc: isPc,
};
};
获取网络信息API
网络信息 API 允许网络应用程序获取有关用户网络连接的信息,例如连接类型(例如 WiFi、蜂窝网络)和其有效带宽。该 API 可用于优化内容传递、管理离线缓存或根据网络条件提供定制体验。
const connection =
navigator.connection ||
navigator.mozConnection ||
navigator.webkitConnection;
const effectiveType = connection.effectiveType; // 有效类型
const downlink = connection.downlink; // 下行链路
电池状态 API
电池状态API提供有关设备电池电量和状态的宝贵信息。它可以让您确定电池是否正在充电,还有多少时间才会完全耗尽,以及当前的电池电量。
navigator.getBattery().then(console.log);
震动 API
对标签页显示隐藏进行事件监听时
navigator.vibrate(3000); // Vibrate for three seconds
判断横竖屏
对手机进行横屏或者竖屏的状态判断
function hengshuping(){
if(window.orientation==180||window.orientation==0){
alert("竖屏状态!")
}
if(window.orientation==90||window.orientation==-90){
alert("横屏状态!")
}
}
window.addEventListener("onorientationchange" in window ? "orientationchange" : "resize", hengshuping, false);
其他
【JavaScript】常用正则
【JavaScript】常用快查 - 客户端
【JavaScript】常用快查 - 断言