MENU

「合集」常用的 JavaScript 代码

2018 年 11 月 04 日 • 开发

document 展开目录

焦点不在当前窗口时改变标题展开目录

  • document.addEventListener('visibilitychange', function () {
  • if (document.hidden) {
  • document.title = '焦点不在当前窗口';
  • } else {
  • document.title = '焦点在当前窗口';
  • }
  • });

解除离开页面检测展开目录

  • document.hasFocus = function () {
  • return true;
  • };

使网页内容(body)可编辑展开目录

开启

  • document.body.contentEditable = 'true';
  • document.designMode = 'on';
  • (function () {
  • let items = document.querySelectorAll('iframe');
  • for (let i = 0; i < items.length; i++) {
  • try {
  • items[i].contentDocument.body.contentEditable = 'true';
  • items[i].contentDocument.designMode = 'on';
  • } catch (err) {
  • console.log(err);
  • }
  • }
  • })();

关闭

  • document.body.contentEditable = 'false';
  • document.designMode = 'off';
  • (function () {
  • let items = document.querySelectorAll('iframe');
  • for (let i = 0; i < items.length; i++) {
  • try {
  • items[i].contentDocument.body.contentEditable = 'false';
  • items[i].contentDocument.designMode = 'off';
  • } catch (err) {
  • console.log(err);
  • }
  • }
  • })();

function 展开目录

查找元素的 Vue 对象展开目录

  • /**
  • * @typedef {object} FunctionResult
  • * @property {boolean} state 是否查找成功
  • * @property {HTMLElement} element Vue 对象所在的元素
  • * @property {object} data 找到的 Vue 对象
  • * @property {object[]} parents 父 Vue 对象
  • */
  • /**
  • * @description 查找元素的 Vue 对象
  • * @param {HTMLElement} el 需要查找的元素
  • * @returns {FunctionResult} 返回查找结果信息
  • */
  • function findElementVue(el) {
  • /** @type {FunctionResult} */
  • const result = {
  • state: false,
  • element: null,
  • data: null,
  • parents: [],
  • };
  • const attrName = '__vue__';
  • // 查找属性
  • while (el) {
  • const data = el[attrName];
  • if (data) {
  • result.state = true;
  • result.element = el;
  • result.data = data;
  • break;
  • } else {
  • el = el.parentElement;
  • }
  • }
  • // 查找父对象
  • if (result.state) {
  • let attrName = '$parent';
  • let parent = result.data[attrName];
  • while (parent) {
  • result.parents.push(parent);
  • parent = parent[attrName];
  • }
  • }
  • return result;
  • }

查找字符 charstr 中第 num 次出现的位置展开目录

  • function findChar(str = '', char = '', num = 1) {
  • var index = str.indexOf(char);
  • num = num - 1;
  • if (num > 0) {
  • for (var i = 0; i < num; i++) {
  • index = str.indexOf(char, index + 1);
  • }
  • }
  • return index;
  • }

格式化时间展开目录

  • /**
  • * @description 格式化时间
  • * @param {(number|string|Date)} [time] 要格式化的时间(默认当前)
  • * @param {string} [format] 需要的格式(默认 yyyy-mm-dd hh:ii:ss)
  • * @returns {string} 格式化后的时间
  • */
  • function formatTime(time = new Date(), format = 'yyyy-mm-dd hh:ii:ss') {
  • let timeType = typeof time;
  • /** @type {Date} */
  • let dateObj = null;
  • if (timeType == 'number' || timeType == 'string') {
  • dateObj = new Date(time);
  • } else if (timeType == 'object') {
  • dateObj = time;
  • }
  • // 时间信息
  • let timeInfo = {
  • // 年月日
  • y: dateObj.getFullYear(),
  • m: dateObj.getMonth() + 1,
  • d: dateObj.getDate(),
  • // 时分秒
  • h: dateObj.getHours(),
  • i: dateObj.getMinutes(),
  • s: dateObj.getSeconds(),
  • };
  • // 格式占位符正则
  • let formatReg = {
  • y: /y+/g,
  • m: /m+/g,
  • d: /d+/g,
  • h: /h+/g,
  • i: /i+/g,
  • s: /s+/g,
  • };
  • for (let key in formatReg) {
  • // 正则匹配
  • let matched = format.match(formatReg[key]);
  • // 获取对应的时间
  • let timeValue = String(timeInfo[key]);
  • // 无匹配结果
  • if (!matched) {
  • continue;
  • }
  • // 根据匹配结果(位数)进行替换
  • matched.forEach(function (v) {
  • let tLength = timeValue.length;
  • let vLength = v.length;
  • // 长度不足,补零
  • if (tLength < vLength) {
  • timeValue = timeValue.padStart(v.length, '0');
  • }
  • // 长度超出,截取
  • // if (tLength > vLength) {
  • // timeValue = timeValue.substring(tLength - vLength);
  • // }
  • // 替换对应的值
  • format = format.replace(v, timeValue);
  • });
  • }
  • return format;
  • }

获取随机的十六进制色展开目录

  • /** 获取随机的十六进制色 */
  • function getHEXColor() {
  • var codes = [
  • '0', '1', '2', '3', '4', '5', '6', '7',
  • '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
  • ];
  • var colors = ['#'];
  • for (let i = 0; i < 6; i++) {
  • let index = Math.floor(Math.random() * 16);
  • colors.push(codes[index]);
  • }
  • return colors.join('');
  • }

获取元素的边界信息展开目录

  • /**
  • * @description 获取元素的边界信息(当前元素必须在父元素内)
  • * @param {Element} curr 当前 DOM 元素
  • * @param {Element} parent 父 DOM 元素
  • */
  • function getBoundaryInfo(curr, parent) {
  • if (!curr || !parent) {
  • console.error('获取失败,缺少参数!');
  • return null;
  • }
  • var result = {};
  • var currRect = curr.getBoundingClientRect();
  • var parentRect = parent.getBoundingClientRect();
  • // 当前元素四角坐标和宽高
  • result.curr = {
  • x0: currRect.left,
  • x1: currRect.right,
  • y0: currRect.top,
  • y1: currRect.bottom,
  • w: currRect.width,
  • h: currRect.height,
  • };
  • // 父元素四角坐标
  • result.parent = {
  • x0: parentRect.left,
  • x1: parentRect.right,
  • y0: parentRect.top,
  • y1: parentRect.bottom,
  • w: parentRect.width,
  • h: parentRect.height,
  • };
  • // 距离
  • result.distance = {
  • top: result.curr.y0 - result.parent.y0,
  • bottom: result.parent.y1 - result.curr.y1,
  • left: result.curr.x0 - result.parent.x0,
  • right: result.parent.x1 - result.curr.x1,
  • };
  • return result;
  • }

获取元素的坐标信息展开目录

  • /**
  • * @description 获取元素的坐标信息(四个角以及宽高)
  • * @param {Element} element DOM 元素
  • */
  • function getElemPosInfo(element) {
  • if (!element) {
  • console.error('获取失败,缺少参数!');
  • return null;
  • }
  • let rect = element.getBoundingClientRect();
  • let data = {
  • x0: rect.left,
  • x1: rect.right,
  • y0: rect.top,
  • y1: rect.bottom,
  • w: rect.width,
  • h: rect.height,
  • };
  • return data;
  • }

获取月份第一天和最后一天的时间戳展开目录

  • /**
  • * @description 获取月份第一天和最后一天的时间戳
  • * @param {number} year 年份
  • * @param {number} month 月份
  • * @returns `{ start: 第一天, end: 最后一天 }`
  • */
  • function getTimestampOfMonth(year, month) {
  • var start = new Date(year, month - 1, 1)
  • var end = new Date(year, month, 0);
  • var time = {
  • start: start.getTime(),
  • end: end.getTime()
  • };
  • return time;
  • }

获取坐标下方的元素展开目录

  • /**
  • * @description 获取坐标下方的元素(从子元素到父元素)
  • * @param {number} x 横坐标
  • * @param {number} y 纵坐标
  • */
  • function elemsFromPoint(x, y) {
  • if (x === undefined || y === undefined) {
  • return [];
  • }
  • x = Math.floor(x);
  • y = Math.floor(y);
  • let item = document.elementFromPoint(x, y);
  • let items = [];
  • if (item) {
  • items.push(item);
  • } else {
  • return [];
  • }
  • while (item.parentElement) {
  • item = item.parentElement;
  • items.push(item);
  • }
  • return items;
  • };

计算字符串的字符数展开目录

  • /**
  • * @description 计算字符串的字符数(数字英文字母 +1,其他 +3)
  • * @param {string} str 被检测的字符串
  • * @returns {number} 字符数
  • */
  • function calcChars(str) {
  • var reg = /[0-9a-zA-Z]/;
  • var sum = 0;
  • for (let i in str) {
  • if (reg.test(str.charAt(i))) {
  • sum += 1;
  • } else {
  • sum += 3;
  • }
  • }
  • return sum;
  • }

加减法精度展开目录

  • /**
  • * @description 加减法精度
  • * @param {string} type 类型(plus、sub)
  • * @param {number} [num1] 数值1,默认为 0
  • * @param {number} [num2] 数值2,默认为 0
  • * @returns {(number|null)} 返回两个数值相加或相减后的结果
  • */
  • function accPlusAndSub(type, num1 = 0, num2 = 0) {
  • var decimalsNum1 = (String(num1).split('.')[1] || '').length;
  • var decimalsNum2 = (String(num2).split('.')[1] || '').length;
  • var decimalsMax = Math.max(decimalsNum1, decimalsNum2);
  • var multiplies = Math.pow(10, decimalsMax);
  • if (type === 'plus') {
  • return ((num1 * multiplies + num2 * multiplies) / multiplies);
  • } else if (type === 'sub') {
  • return ((num1 * multiplies - num2 * multiplies) / multiplies);
  • } else {
  • return null;
  • }
  • }

检测用户是否离开页面展开目录

  • /**
  • * @description 检测用户是否离开页面(一秒检测一次)
  • * @param {object} [options] 配置选项
  • * @param {function} [options.onblur] 用户离开页面时的回调函数
  • * @param {function} [options.onfocus] 用户返回页面时的回调函数
  • * @param {string} [options.blurDelay] 设定用户离开页面多久后才调用 onblur
  • * - 单位为秒
  • * - 默认 0
  • * @param {string} [options.timerName] 定时器名称
  • * - 用于 setInterval()
  • * - 默认 tCheckPageBlur
  • */
  • function checkPageBlur(options) {
  • var config = {
  • onblur: null,
  • onfocus: null,
  • blurDelay: 0,
  • timerName: 'tCheckPageBlur',
  • };
  • Object.assign(config, options);
  • var timerName = config.timerName; // 定时器名称
  • var checkDelay = 0; // 延时
  • var blurTriggered = false; // 标记状态
  • clearInterval(window[timerName]);
  • window[timerName] = setInterval(function () {
  • var isFocus = document.hasFocus();
  • if (isFocus && blurTriggered) {
  • // 在页面且触发过 blur
  • blurTriggered = false;
  • checkDelay = 0;
  • try {
  • config.onfocus && (config.onfocus());
  • } catch (err) {
  • console.error('[检测] 回调函数 onfocus 出错\n', err);
  • }
  • } else if (!isFocus && !blurTriggered) {
  • // 不在页面且未触发 blur
  • if (checkDelay >= config.blurDelay) {
  • blurTriggered = true;
  • checkDelay = 0;
  • try {
  • config.onblur && (config.onblur());
  • } catch (err) {
  • console.error('[检测] 回调函数 onblur 出错\n', err);
  • }
  • } else {
  • checkDelay += 1;
  • }
  • }
  • }, 1000);
  • }
  • // 调用
  • checkPageBlur({
  • onblur: function () {
  • console.log('[检测] 用户离开页面');
  • },
  • onfocus: function () {
  • console.log('[检测] 用户返回页面');
  • },
  • });

解析 URL 地址的参数(?=...)为一个对象展开目录

  • function queriesToObj(url = '') {
  • var split = url.split('?')[1];
  • var arr = split.split('&');
  • var obj = {};
  • arr.forEach(function (item) {
  • var kv = item.split('=');
  • obj[kv[0]] = kv[1];
  • });
  • return obj;
  • }

矩形碰撞检测展开目录

  • /**
  • * @description 矩形碰撞检测
  • * @param {Element} elemA 当前元素
  • * @param {Element} elemB 目标元素
  • * @param {boolean} [checkAside] 是否包含边缘碰撞,默认包含
  • * @returns {object} `{ error: 是否检测失败, hit: 是否碰撞 }`
  • */
  • function rectColisionCheck(elemA, elemB, checkAside = true) {
  • const result = {
  • error: false,
  • hit: false,
  • };
  • if (!(elemA && elemB)) {
  • console.error('缺少参数');
  • result.error = true;
  • return result;
  • }
  • const rectA = elemA.getBoundingClientRect();
  • const rectB = elemB.getBoundingClientRect();
  • if (checkAside) {
  • result.hit = !(
  • rectA.bottom < rectB.top ||
  • rectA.left > rectB.right ||
  • rectA.top > rectB.bottom ||
  • rectA.right < rectB.left
  • );
  • } else {
  • result.hit = !(
  • rectA.bottom <= rectB.top ||
  • rectA.left >= rectB.right ||
  • rectA.top >= rectB.bottom ||
  • rectA.right <= rectB.left
  • );
  • }
  • return result;
  • }

设置事件对象属性展开目录

  • /**
  • * @description 设置事件对象属性
  • * @param {Eveny} ev 事件对象
  • * @param {object} props 要设置的属性
  • */
  • function setEvProps(ev, props = {}) {
  • if (ev) {
  • for (let key in props) {
  • Object.defineProperty(ev, key, {
  • configurable: true,
  • enumerable: true,
  • get: function () {
  • return props[key];
  • },
  • });
  • }
  • }
  • }

通过点路径访问对象属性展开目录

  • /**
  • * @description 通过点路径访问对象属性
  • * @param {object} obj
  • * @param {string} path
  • */
  • function getObjValue(obj, path = '') {
  • if (typeof obj !== 'object') {
  • console.error('访问失败,参数 obj 错误!');
  • return;
  • }
  • if (typeof path !== 'string') {
  • console.error('访问失败,参数 path 错误!');
  • return;
  • }
  • if (path === '') {
  • return obj;
  • }
  • return path.split('.').reduce((a, b) => {
  • return (a === undefined ? a : a[b]);
  • }, obj);
  • }

暂停执行代码一段时间展开目录

  • /**
  • * @description 暂停执行代码一段时间
  • * @param {number} [time] 时长(毫秒),默认 1000
  • * @returns {Promise} Promise
  • */
  • function sleep(time = 1000) {
  • return new Promise(function (resolve) {
  • setTimeout(() => {
  • resolve();
  • }, time);
  • });
  • }
  • await sleep(1000);

字符串转文件展开目录

  • /**
  • * @description 字符串转文件
  • * @param {string} data 字符串数据
  • * @param {string} filename 文件名
  • * @param {string} filetype 文件类型(MIME)
  • */
  • function strToFile(data = '', filename = 'export.txt', filetype = 'text/plain') {
  • // 转为 Blob
  • var strToBlob = new Blob([data], { type: filetype });
  • // URL 对象兼容性处理
  • var urlObject = window.URL || window.webkitURL || window;
  • // 创建对象 URL
  • var blobURL = urlObject.createObjectURL(strToBlob);
  • // 创建 a 元素
  • var aElem = document.createElement('a');
  • // 设置属性
  • aElem.classList.add('hidden');
  • aElem.download = filename;
  • aElem.href = blobURL;
  • aElem.target = '_blank';
  • // 添加元素
  • document.body.appendChild(aElem);
  • // 模拟点击
  • aElem.click();
  • // 移除元素
  • aElem.remove();
  • // 释放对象
  • urlObject.revokeObjectURL(blobURL);
  • }
最后编辑于: 2022 年 07 月 23 日