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

请叫我海龟先生
• 阅读 1411

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'
点赞
收藏
评论区
推荐文章
blmius blmius
2年前
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:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
记录 30 seconds of code 项目个人觉得中有价值的片段或者小技巧(二)
DF系列1、防抖函数,限制高频触发jsconstdebounce(fn,ms0)lettimeoutId;returnfunction(...args)clearTimeout(timeoutId);timeoutIdsetTimeout(()fn.apply(this,args),ms);
记录 30 seconds of code 项目个人觉得中有价值的片段或者小技巧 (一)
AC系列1、号的隐式类型转换使用js3//31,2,3.slice(1)//将3转换为了32、日期的转换jsconstaddDaysToDate(date,n)constdnewDate(date);d.setDate(d.getDate()n);returnd.toISOS
Karen110 Karen110
2年前
一篇文章带你了解JavaScript日期
日期对象允许您使用日期(年、月、日、小时、分钟、秒和毫秒)。一、JavaScript的日期格式一个JavaScript日期可以写为一个字符串:ThuFeb02201909:59:51GMT0800(中国标准时间)或者是一个数字:1486000791164写数字的日期,指定的毫秒数自1970年1月1日00:00:00到现在。1\.显示日期使用
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
记录 30 seconds of code 项目个人觉得中有价值的片段或者小技巧(四)
JZ系列获取数组元素下标(findIndex的实现)jsconstlinearSearch(arr,item)for(constiinarr)if(arriitem)returni;return1;;linearSearch(2,9,9,9);//1linearSearch(
Stella981 Stella981
2年前
Android So动态加载 优雅实现与原理分析
背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这