记录 30 seconds of code 项目个人觉得中有价值的片段或者小技巧(三)

请叫我海龟先生
• 阅读 1104

G - I 系列

获取元素距离顶部的距离

const getVerticalOffset = el => {
  let offset = el.offsetTop,
    _el = el;
  while (_el.offsetParent) {
    _el = _el.offsetParent;
    offset += _el.offsetTop;
  }
  return offset;
};
  • offsetTop 是相对其父元素的距离,这里主要通过累加的方式来获取
  • 对于嵌套较深的节点,可能其他 api (元素位置信息)来的更快些

根据给定函数对数组元素进行分组

const groupBy = (arr, fn) =>
  arr
    .map(typeof fn === 'function' ? fn : val => val[fn])
    .reduce((acc, val, i) => {
      acc[val] = (acc[val] || []).concat(arr[i]);
      return acc;
    }, {});

groupBy([6.1, 4.2, 6.3], Math.floor); // {4: [4.2], 6: [6.1, 6.3]}
groupBy(['one', 'two', 'three'], 'length'); // {3: ['one', 'two'], 5: ['three']}
  • 第一次 map 的时候就将分组条件划分为一个数组
  • reduce 时再以,条件做为key值,往其中添加值

检查一维数组中是否有重复的值

const hasDuplicates = arr => new Set(arr).size !== arr.length;

hasDuplicates([0, 1, 1, 2]); // true
hasDuplicates([0, 1, 2, 3]); // false
  • 转化为 Set 对象,再通过size与原数组是否相等
  • Set 后就去重了,size可理解为长度

检查是否为绝对url格式

const isAbsoluteURL = str => /^[a-z][a-z0-9+.-]*:/.test(str);

isAbsoluteURL('https://google.com'); // true
isAbsoluteURL('ftp://www.myserver.net'); // true
isAbsoluteURL('/foo/bar'); // false

类数组的检查

const isArrayLike = obj =>
  obj != null && typeof obj[Symbol.iterator] === 'function';


isArrayLike([1, 2, 3]); // true
isArrayLike(document.querySelectorAll('.className')); // true
isArrayLike('abc'); // true
isArrayLike(null); // false

检查一个函数是否是异步函数

const isAsyncFunction = val =>
  Object.prototype.toString.call(val) === '[object AsyncFunction]';

isAsyncFunction(function() {}); // false
isAsyncFunction(async function() {}); // true

// 类型为 AsyncFunction,类似的还要检查是否为 Promise

const isPromiseLike = obj =>
  obj !== null &&
  (typeof obj === 'object' || typeof obj === 'function') &&
  typeof obj.then === 'function';

isPromiseLike({
  then: function() {
    return '';
  }
}); // true
isPromiseLike(null); // false
isPromiseLike({}); // false

判断当前页面是否可见

const isBrowserTabFocused = () => !document.hidden;

isBrowserTabFocused(); // true
// 更多依赖 Page Visibility 这个API吧,权当了解下

检查值是否是有下铺的JSON

const isValidJSON = str => {
  try {
    JSON.parse(str);
    return true;
  } catch (e) {
    return false;
  }
};
// 之前同时事也问过此问题,当时确定没想到可以 try catch 的方式来判断

isValidJSON('{"name":"Adam","age":20}'); // true
isValidJSON('{"name":"Adam",age:"20"}'); // false
isValidJSON(null); // true

实现一个 findIndex

const linearSearch = (arr, item) => {
  for (const i in arr) {
    if (arr[i] === item) return +i;
  }
  return -1;
};

linearSearch([2, 9, 9], 9); // 1
linearSearch([2, 9, 9], 7); // -1

实现事件一次绑定

// 这个是运用添加事件参数实现的
const listenOnce = (el, evt, fn) =>
  el.addEventListener(evt, fn, { once: true });
  // 可以传入 option(对象) 也可以传入 useCapture(布尔)

listenOnce(
  document.getElementById('my-id'),
  'click',
  () => console.log('Hello world')
); 
// 通过闭包函数实现
const once = fn => {
  let called = false;
  return function(...args) {
    if (called) return;
    called = true;
    return fn.apply(this, args);
  };
};

const startApp = function(event) {
  console.log(this, event); // document.body, MouseEvent
};
document.body.addEventListener('click', once(startApp));

// 现在多数框架也有对应实现,比如 VUE @click.once,起初并未运用,也没想过实现原理,现在知道了,好像也不难实现 哈哈

实现一个缓存(记忆)函数

const memoize = fn => {
  const cache = new Map();
  const cached = function (val) {
    return cache.has(val)
      ? cache.get(val)
      : cache.set(val, fn.call(this, val)) && cache.get(val);
      // && 返回cache.get(val),如果是比较,&&的才返回布尔值
  };
  cached.cache = cache;
  return cached;
};

// See the `anagrams` snippet.
const anagramsCached = memoize(anagrams);
anagramsCached('javascript'); // takes a long time
anagramsCached('javascript'); // returns virtually instantly since it's cached
console.log(anagramsCached.cache); // The cached anagrams map

将对象转换成查询字符串形式 ?key=value&xxx=aaa

// Object.entries 直接将对象转为 数组形式的 key-value
const objectToQueryString = queryParameters => {
  return queryParameters
    ? Object.entries(queryParameters).reduce(
        (queryString, [key, val], index) => {
          const symbol = queryString.length === 0 ? '?' : '&';
          queryString +=
            typeof val === 'string' ? `${symbol}${key}=${val}` : '';
          return queryString;
        },
        ''
      )
    : '';
};
objectToQueryString({ page: '1', size: '2kg', key: undefined });
// '?page=1&size=2kg'
点赞
收藏
评论区
推荐文章
秃头王路飞 秃头王路飞
1星期前
webpack5手撸vue2脚手架
webpack5手撸vue相信工作个12年的小伙伴们在面试的时候多多少少怕被问到关于webpack方面的知识,本菜鸟最近闲来无事,就尝试了手撸了下vue2的脚手架,第一次发帖实在是没有经验,望海涵。 language JavaScript "name": "vuecliversion2", "version": "1.0.0", "desc
记录 30 seconds of code 项目个人觉得中有价值的片段或者小技巧(二)
D F 系列 1、防抖函数,限制高频触发jsconst debounce (fn, ms 0) let timeoutId; return function(...args) clearTimeout(timeoutId); timeoutId setTimeout(() fn.apply(this, args), ms);
Jacquelyn38 Jacquelyn38
1年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。 1、使用解构获取json数据let jsonData   id: 1, status: "OK", data: ['a', 'b'] ; let  id, status, data: number   jsonData; console.log(id, status, number )
blmius blmius
1年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录 问题 用navicat导入数据时,报错: 原因这是因为当前的MySQL不支持datetime为0的情况。 解决修改sql\mode: sql\mode:SQL Mode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。 全局s
记录 30 seconds of code 项目个人觉得中有价值的片段或者小技巧 (一)
A C 系列 1、+ 号的隐式类型转换使用js+[3] //3+[1,2,3].slice(1) //将 [3] 转换为了3 2、日期的转换jsconst addDaysToDate (date, n) const d new Date(date); d.setDate(d.getDate() + n); return d.toISOS
小森森 小森森
1星期前
校园表白墙微信小程序V1.0 SayLove -基于微信云开发-一键快速搭建,开箱即用
后续会继续更新,敬请期待2.0全新版本 欢迎添加左边的微信一起探讨!项目地址:](https://www.aliyun.com/activity/daily/bestoffer?userCodesskuuw5n) \2. Bug修复更新日历 2. 情侣脸功能大家不要使用了,现在阿里云的接口已经要收费了(土豪请随意), \ \ 和 注意
Stella981 Stella981
11个月前
CentOS6.7 i686上安装JDK7
内核版本: [root@heima01 java]# uname -a Linux heima01 2.6.32-573.el6.i686 #1 SMP Thu Jul 23 12:37:35 UTC 2015 i686 i686 i386 GNU/Linux 发行版本: [root@heima01 java
Stella981 Stella981
11个月前
Android So动态加载 优雅实现与原理分析
> 背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载. ![](https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png) 点击上方“蓝字”关注我
请叫我海龟先生 请叫我海龟先生
11个月前
记录 30 seconds of code 项目个人觉得中有价值的片段或者小技巧(四)
J Z 系列 获取数组元素下标(findIndex的实现)jsconst linearSearch (arr, item) for (const i in arr) if (arr[i] item) return +i; return 1;;linearSearch([2, 9, 9], 9); // 1linearSearch([
Stella981 Stella981
11个月前
Angular material mat
Icon Icon Name mat-icon code _add\_comment_ add comment icon <mat-icon> add\_comment</mat-icon> _attach\_file_ attach file icon <mat-icon> attach\_file</mat-icon> _attach\