参考文章:
匹配最外层HTML标签名
var rquickExpr = /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;
console.log(rquickExpr.exec('<h1><span></span></h1>')[1]); // => "h1"
console总结
普通打印
普通(基本)的打印方法有以下四种,都可接收多个参数:
console.log
:用得最多的一种,基本上没有任何限制;console.info
:打印信息;console.error
:打印报错内容;console.warn
:打印警告内容。
示例:
console.log('log: ', 'log content.');
console.info('info: ', 'info content.');
console.error('error: ', 'error content.');
console.warn('warn: ', 'warn content.');
效果:
分组打印
分组打印用到的是console.group()
和console.groupEnd()
方法,用法如下:
console.group('Group 1: ');
console.log('1. Dva');
console.log('2. Joe');
console.groupEnd();
console.group('Group 2: ');
console.log('1. WJT20');
console.groupEnd();
效果:
表格打印
表格打印方法console.table()
可以美观地打印数组和对象:
console.table({
name: 'WJT20',
id: 1
});
console.table([
{ name: 'WJT20', id: 1 },
{ name: 'Dva', id: 2 }
]);
效果:
计数和计时
计数即console.count()
,传入的参数表示字段,每次调用都会统计这个字段调用的次数:
for (var i = 0; i < 5; i++) {
console.count('counter'); // 共调用5次
}
计时常用于计算程序花费的时长,用的是console.time()
和console.timeEnd()
:
console.time('test');
for (var i = 0; i < 1000; i++) {} // 1000次循环
console.timeEnd('test');
条件打印和打印跟踪
条件打印即console.assert()
:
for (var i = 0; i < 10; i++) {
console.assert(i >= 5, { msg: i + ' is less than 5' });
}
打印跟踪即console.trace()
:
console.trace();
浏览器判断原则
代码:
var sUserAgent = navigator.userAgent.toLowerCase();
var browser = {
bIsIOS: !!navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/),
bIsUc: sUserAgent.match(/ucweb/i) == "ucweb",
bIsAndroid: sUserAgent.match(/android/i) == "android",
bIsAndroidVersion: Number(sUserAgent.substr(sUserAgent.indexOf('android') + 8, 3)),
bIsQQ: sUserAgent.match(/qq/i) == "qq",
bIsWechat: sUserAgent.match(/micromessenger/i) == "micromessenger",
bIsWeibo: sUserAgent.match(/weibo/i) == "weibo",
bIsHuawei: sUserAgent.match(/huawei/i) == "huawei"
};
检查手机号码格式
代码:
function checkPhoneFormat(phone) {
var pattern = /^0?1[3|4|5|7|8][0-9]\d{8}$/;
if (pattern.test(phone)) {
return true;
} else {
return false;
}
};
获取当前URL查询字符串参数
代码:
function parseQueryString(search) {
var str = search.slice(1);
var arr = str.split('&');
var obj = {};
for (var i = 0; i < arr.length; i++) {
// 一般参数字符串都经过编码,使用decodeURIComponent()方法将键和值转为原始值
var item = arr[i].split('=');
var key = decodeURIComponent(item[0]);
var value = decodeURIComponent(item[1]);
obj[key] = value;
}
return obj;
}
console.log(parseQueryString(location.search)); // {token: "bc6fc548-d04e-4210-a4db-d0bc397a4f09", account: "jt_w"}
CRT日期转换
代码:
function translateCRT(CRTDate) {
var time = CRTDate.replace(new RegExp(' CST', 'gm'), '');
var now = new Date(time);
var year = now.getFullYear();
var month = now.getMonth() + 1;
var date = now.getDate();
var hh = now.getHours();
var mm = now.getMinutes();
return {
dataObj: now,
year: year,
month: month,
date: date,
hour: hh,
minute: mm
}
}
使用touchstart代替移动端click事件
代码:
var dialogEl = document.getElementById('dialog-container');
dialogEl.addEventListener('touchstart', function () {
...
});
解析:
在移动端,touchstart 比 click 要灵敏得多,但是何时该使用 touchstart,何时该使用 click,应视具体场景而定。
数组去重
代码:
function unique (arr) {
var newArr = [];
var isRepeated = false;
for (var i = 0; i < arr.length; i++) {
isRepeated = false;
for (var j = 0; j < newArr.length; j++) {
if (newArr[j] === arr[i]) {
isRepeated = true;
break;
}
}
if (!isRepeated) {
newArr.push(arr[i]);
}
}
return newArr;
}
console.log(unique([1, 2, 3, 4, undefined, 1, null, undefined, 3, NaN, 5, NaN])); // [1, 2, 3, 4, null, 5]
解析:
对于 undefined、null、NaN 等特殊值,for 循环会自动忽视这些值,所以不考虑这些值的去重,另外,Object 的相等判断又是另一个复杂知识了,这里也不考虑。
获取YYYY-MM-DD格式日期
代码:
function getTimestamp(date, spliter) {
if (!date) {
date = new Date();
}
if (!spliter) {
spliter = '-';
}
function format(target, figure) {
target = target.toString();
for (var i = 0; i < (figure - target.length); i++) {
target = '0' + target;
}
return target;
}
var y = format(date.getFullYear(), 4);
var m = format(date.getMonth() + 1, 2);
var d = format(date.getDate(), 2);
return y + spliter + m + spliter + d;
}
console.log(getTimestamp());
类型获取
代码:
function checkedType(target) {
return Object.prototype.toString.call(target).slice(8, -1);
}
深拷贝
代码:
// 定义检测数据类型的功能函数
function checkedType(target) {
return Object.prototype.toString.call(target).slice(8, -1);
}
// 实现深度克隆---对象/数组
function clone(target) {
// 判断拷贝的数据类型
// 初始化变量result 成为最终克隆的数据
var result;
var targetType = checkedType(target);
if (targetType === 'Object') {
result = {};
} else if (targetType === 'Array') {
result = [];
} else {
return target;
}
// 遍历目标数据
for (var i in target) {
// 获取遍历数据结构的每一项值。
var value = target[i];
// 判断目标结构里的每一值是否存在对象/数组
if (checkedType(value) === 'Object' || checkedType(value) === 'Array') {
// 对象/数组里嵌套了对象/数组
// 继续遍历获取到value值
result[i] = clone(value);
} else {
// 获取到value值是基本的数据类型或者是函数。
result[i] = value;
}
}
return result;
}
节流
代码:
function throttle(fn, time) {
var ifWork = true; // 用闭包保存一个计时器启动标记
return function () {
var params = arguments;
if (ifWork) {
// 一旦计时器启动,则将标记置为false
ifWork = false;
setTimeout(function () {
// 注意绑定上下文环境
fn.apply(this, params);
ifWork = true;
}, time);
}
};
}
防抖
代码:
function debounce(fn, time) {
var timer = null; // 用闭包把计时器对象保存下来
return function () {
var params = arguments;
if (timer) {
// 清除掉已存在的计时器
clearTimeout(timer);
}
timer = setTimeout(function () {
// 注意绑定上下文环境
fn.apply(this, params);
}, time);
};
}
解决js小数加法精度不准确问题
代码:
function getFloatAddResult(num1, num2) {
var r1; // 第一个数字小数点后的字符个数
var r2; // 第二个数字小数点后的字符个数
var c1 = num1.toString().split('.'); // 第一个数字小数点后的内容
var c2 = num2.toString().split('.'); // 第二个数字小数点后的内容
r1 = c1[1] ? c1[1].length : 0;
r2 = c2[1] ? c2[1].length : 0;
var m = Math.pow(10, Math.max(r1, r2))
return (num1 * m + num2 * m) / m
}
console.log(getFloatAddResult(1.00003, 2.00000000005)); // 3.00003000005
滚动列表滚动到顶部/左侧
代码:
// 滚动到顶部
document.getElementById(..).scrollTop = 0;
// 滚动到左侧
document.getElementById(..).scrollLeft = 0;
手动水平滚动列表以使某项居中
代码:
/**
* 修正上层导航栏ui
*/
function invokeUpdateNavigationBarSelectedUI(navigationBarRefEl) {
const viewW = navigationBarRefEl.getBoundingClientRect().width;
const targetCategoryEl = document.querySelector(`.scroll-view-item[data-product-category-id="${ this.selectedCategoryId }"]`);
if (targetCategoryEl) {
navigationBarRefEl.scrollTo(targetCategoryEl.offsetLeft - viewW / 2, 0)
}
}
手动触发新标签页打开链接
代码:
const aEl = document.createElement('a');
aEl.setAttribute('href', 'https://img.alicdn.com/tfs/TB1aUWDnAL0gK0jSZFAXXcA9pXa-468-1236.jpg');
aEl.setAttribute('target', '_blank'); // 新标签页打开链接
aEl.setAttribute('download', '文件名'); // 手动触发文件下载,指定文件名(同源文件可以触发下载,非同源则只会打开新标签页)
const event = new MouseEvent('click');
aEl.dispatchEvent(event)
判断当前设备是否为iPhoneX
需要结合 css 媒体查询实现,首先是 css 部分:
@media only screen and (min-height: 812px) and (max-height: 1023px) {
:root {
// 此处注入全局iPhoneX标识
--is-phonex: 1;
}
}
然后 JavaScript 再获取此标识的值:
var isPhonex = window
.getComputedStyle(document.documentElement)
.getPropertyValue('--is-phonex')
.trim() === '1';
判断URL格式
代码:
var url = 'https://juejin.cn/search?query=%E6%AD%A3%E5%88%99';
(/^(f|ht){1}(tp|tps):\/\/([\w-]+\.)+[\w-]+(\/[\w- ./?%&=]*)?/).test(url)