参考文章:

  1. 知道这 20 个正则表达式,能让你少写 1,000 行代码

匹配最外层HTML标签名

  1. var rquickExpr = /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;
  2. console.log(rquickExpr.exec('<h1><span></span></h1>')[1]); // => "h1"

console总结

普通打印

普通(基本)的打印方法有以下四种,都可接收多个参数:

  1. console.log:用得最多的一种,基本上没有任何限制;
  2. console.info:打印信息;
  3. console.error:打印报错内容;
  4. console.warn:打印警告内容。

示例:

  1. console.log('log: ', 'log content.');
  2. console.info('info: ', 'info content.');
  3. console.error('error: ', 'error content.');
  4. console.warn('warn: ', 'warn content.');

效果:
image.png

分组打印

分组打印用到的是console.group()console.groupEnd()方法,用法如下:

  1. console.group('Group 1: ');
  2. console.log('1. Dva');
  3. console.log('2. Joe');
  4. console.groupEnd();
  5. console.group('Group 2: ');
  6. console.log('1. WJT20');
  7. console.groupEnd();

效果:
image.png

表格打印

表格打印方法console.table()可以美观地打印数组和对象:

  1. console.table({
  2. name: 'WJT20',
  3. id: 1
  4. });
  5. console.table([
  6. { name: 'WJT20', id: 1 },
  7. { name: 'Dva', id: 2 }
  8. ]);

效果:
image.png

计数和计时

计数即console.count(),传入的参数表示字段,每次调用都会统计这个字段调用的次数:

  1. for (var i = 0; i < 5; i++) {
  2. console.count('counter'); // 共调用5次
  3. }

计时常用于计算程序花费的时长,用的是console.time()console.timeEnd()

  1. console.time('test');
  2. for (var i = 0; i < 1000; i++) {} // 1000次循环
  3. console.timeEnd('test');

条件打印和打印跟踪

条件打印即console.assert()

  1. for (var i = 0; i < 10; i++) {
  2. console.assert(i >= 5, { msg: i + ' is less than 5' });
  3. }

打印跟踪即console.trace()

  1. console.trace();

浏览器判断原则

代码:

  1. var sUserAgent = navigator.userAgent.toLowerCase();
  2. var browser = {
  3. bIsIOS: !!navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/),
  4. bIsUc: sUserAgent.match(/ucweb/i) == "ucweb",
  5. bIsAndroid: sUserAgent.match(/android/i) == "android",
  6. bIsAndroidVersion: Number(sUserAgent.substr(sUserAgent.indexOf('android') + 8, 3)),
  7. bIsQQ: sUserAgent.match(/qq/i) == "qq",
  8. bIsWechat: sUserAgent.match(/micromessenger/i) == "micromessenger",
  9. bIsWeibo: sUserAgent.match(/weibo/i) == "weibo",
  10. bIsHuawei: sUserAgent.match(/huawei/i) == "huawei"
  11. };

检查手机号码格式

代码:

  1. function checkPhoneFormat(phone) {
  2. var pattern = /^0?1[3|4|5|7|8][0-9]\d{8}$/;
  3. if (pattern.test(phone)) {
  4. return true;
  5. } else {
  6. return false;
  7. }
  8. };

获取当前URL查询字符串参数

代码:

  1. function parseQueryString(search) {
  2. var str = search.slice(1);
  3. var arr = str.split('&');
  4. var obj = {};
  5. for (var i = 0; i < arr.length; i++) {
  6. // 一般参数字符串都经过编码,使用decodeURIComponent()方法将键和值转为原始值
  7. var item = arr[i].split('=');
  8. var key = decodeURIComponent(item[0]);
  9. var value = decodeURIComponent(item[1]);
  10. obj[key] = value;
  11. }
  12. return obj;
  13. }
  14. console.log(parseQueryString(location.search)); // {token: "bc6fc548-d04e-4210-a4db-d0bc397a4f09", account: "jt_w"}

CRT日期转换

代码:

  1. function translateCRT(CRTDate) {
  2. var time = CRTDate.replace(new RegExp(' CST', 'gm'), '');
  3. var now = new Date(time);
  4. var year = now.getFullYear();
  5. var month = now.getMonth() + 1;
  6. var date = now.getDate();
  7. var hh = now.getHours();
  8. var mm = now.getMinutes();
  9. return {
  10. dataObj: now,
  11. year: year,
  12. month: month,
  13. date: date,
  14. hour: hh,
  15. minute: mm
  16. }
  17. }

使用touchstart代替移动端click事件

代码:

  1. var dialogEl = document.getElementById('dialog-container');
  2. dialogEl.addEventListener('touchstart', function () {
  3. ...
  4. });

解析:

在移动端,touchstart 比 click 要灵敏得多,但是何时该使用 touchstart,何时该使用 click,应视具体场景而定。

数组去重

代码:

  1. function unique (arr) {
  2. var newArr = [];
  3. var isRepeated = false;
  4. for (var i = 0; i < arr.length; i++) {
  5. isRepeated = false;
  6. for (var j = 0; j < newArr.length; j++) {
  7. if (newArr[j] === arr[i]) {
  8. isRepeated = true;
  9. break;
  10. }
  11. }
  12. if (!isRepeated) {
  13. newArr.push(arr[i]);
  14. }
  15. }
  16. return newArr;
  17. }
  18. 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格式日期

代码:

  1. function getTimestamp(date, spliter) {
  2. if (!date) {
  3. date = new Date();
  4. }
  5. if (!spliter) {
  6. spliter = '-';
  7. }
  8. function format(target, figure) {
  9. target = target.toString();
  10. for (var i = 0; i < (figure - target.length); i++) {
  11. target = '0' + target;
  12. }
  13. return target;
  14. }
  15. var y = format(date.getFullYear(), 4);
  16. var m = format(date.getMonth() + 1, 2);
  17. var d = format(date.getDate(), 2);
  18. return y + spliter + m + spliter + d;
  19. }
  20. console.log(getTimestamp());

类型获取

代码:

  1. function checkedType(target) {
  2. return Object.prototype.toString.call(target).slice(8, -1);
  3. }

深拷贝

代码:

  1. // 定义检测数据类型的功能函数
  2. function checkedType(target) {
  3. return Object.prototype.toString.call(target).slice(8, -1);
  4. }
  5. // 实现深度克隆---对象/数组
  6. function clone(target) {
  7. // 判断拷贝的数据类型
  8. // 初始化变量result 成为最终克隆的数据
  9. var result;
  10. var targetType = checkedType(target);
  11. if (targetType === 'Object') {
  12. result = {};
  13. } else if (targetType === 'Array') {
  14. result = [];
  15. } else {
  16. return target;
  17. }
  18. // 遍历目标数据
  19. for (var i in target) {
  20. // 获取遍历数据结构的每一项值。
  21. var value = target[i];
  22. // 判断目标结构里的每一值是否存在对象/数组
  23. if (checkedType(value) === 'Object' || checkedType(value) === 'Array') {
  24. // 对象/数组里嵌套了对象/数组
  25. // 继续遍历获取到value值
  26. result[i] = clone(value);
  27. } else {
  28. // 获取到value值是基本的数据类型或者是函数。
  29. result[i] = value;
  30. }
  31. }
  32. return result;
  33. }

节流

代码:

  1. function throttle(fn, time) {
  2. var ifWork = true; // 用闭包保存一个计时器启动标记
  3. return function () {
  4. var params = arguments;
  5. if (ifWork) {
  6. // 一旦计时器启动,则将标记置为false
  7. ifWork = false;
  8. setTimeout(function () {
  9. // 注意绑定上下文环境
  10. fn.apply(this, params);
  11. ifWork = true;
  12. }, time);
  13. }
  14. };
  15. }

防抖

代码:

  1. function debounce(fn, time) {
  2. var timer = null; // 用闭包把计时器对象保存下来
  3. return function () {
  4. var params = arguments;
  5. if (timer) {
  6. // 清除掉已存在的计时器
  7. clearTimeout(timer);
  8. }
  9. timer = setTimeout(function () {
  10. // 注意绑定上下文环境
  11. fn.apply(this, params);
  12. }, time);
  13. };
  14. }

解决js小数加法精度不准确问题

代码:

  1. function getFloatAddResult(num1, num2) {
  2. var r1; // 第一个数字小数点后的字符个数
  3. var r2; // 第二个数字小数点后的字符个数
  4. var c1 = num1.toString().split('.'); // 第一个数字小数点后的内容
  5. var c2 = num2.toString().split('.'); // 第二个数字小数点后的内容
  6. r1 = c1[1] ? c1[1].length : 0;
  7. r2 = c2[1] ? c2[1].length : 0;
  8. var m = Math.pow(10, Math.max(r1, r2))
  9. return (num1 * m + num2 * m) / m
  10. }
  11. console.log(getFloatAddResult(1.00003, 2.00000000005)); // 3.00003000005

滚动列表滚动到顶部/左侧

代码:

  1. // 滚动到顶部
  2. document.getElementById(..).scrollTop = 0;
  3. // 滚动到左侧
  4. document.getElementById(..).scrollLeft = 0;

手动水平滚动列表以使某项居中

代码:

  1. /**
  2. * 修正上层导航栏ui
  3. */
  4. function invokeUpdateNavigationBarSelectedUI(navigationBarRefEl) {
  5. const viewW = navigationBarRefEl.getBoundingClientRect().width;
  6. const targetCategoryEl = document.querySelector(`.scroll-view-item[data-product-category-id="${ this.selectedCategoryId }"]`);
  7. if (targetCategoryEl) {
  8. navigationBarRefEl.scrollTo(targetCategoryEl.offsetLeft - viewW / 2, 0)
  9. }
  10. }

手动触发新标签页打开链接

代码:

  1. const aEl = document.createElement('a');
  2. aEl.setAttribute('href', 'https://img.alicdn.com/tfs/TB1aUWDnAL0gK0jSZFAXXcA9pXa-468-1236.jpg');
  3. aEl.setAttribute('target', '_blank'); // 新标签页打开链接
  4. aEl.setAttribute('download', '文件名'); // 手动触发文件下载,指定文件名(同源文件可以触发下载,非同源则只会打开新标签页)
  5. const event = new MouseEvent('click');
  6. aEl.dispatchEvent(event)

判断当前设备是否为iPhoneX

需要结合 css 媒体查询实现,首先是 css 部分:

  1. @media only screen and (min-height: 812px) and (max-height: 1023px) {
  2. :root {
  3. // 此处注入全局iPhoneX标识
  4. --is-phonex: 1;
  5. }
  6. }

然后 JavaScript 再获取此标识的值:

  1. var isPhonex = window
  2. .getComputedStyle(document.documentElement)
  3. .getPropertyValue('--is-phonex')
  4. .trim() === '1';

判断URL格式

代码:

  1. var url = 'https://juejin.cn/search?query=%E6%AD%A3%E5%88%99';
  2. (/^(f|ht){1}(tp|tps):\/\/([\w-]+\.)+[\w-]+(\/[\w- ./?%&=]*)?/).test(url)