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

G - I 系列

获取元素距离顶部的距离

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

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

1const groupBy = (arr, fn) => 2 arr 3 .map(typeof fn === 'function' ? fn : val => val[fn]) 4 .reduce((acc, val, i) => { 5 acc[val] = (acc[val] || []).concat(arr[i]); 6 return acc; 7 }, {}); 8 9groupBy([6.1, 4.2, 6.3], Math.floor); // {4: [4.2], 6: [6.1, 6.3]} 10groupBy(['one', 'two', 'three'], 'length'); // {3: ['one', 'two'], 5: ['three']}
  • 第一次 map 的时候就将分组条件划分为一个数组
  • reduce 时再以,条件做为key值,往其中添加值

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

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

检查是否为绝对url格式

1const isAbsoluteURL = str => /^[a-z][a-z0-9+.-]*:/.test(str); 2 3isAbsoluteURL('https://google.com'); // true 4isAbsoluteURL('ftp://www.myserver.net'); // true 5isAbsoluteURL('/foo/bar'); // false

类数组的检查

1const isArrayLike = obj => 2 obj != null && typeof obj[Symbol.iterator] === 'function'; 3 4 5isArrayLike([1, 2, 3]); // true 6isArrayLike(document.querySelectorAll('.className')); // true 7isArrayLike('abc'); // true 8isArrayLike(null); // false

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

1const isAsyncFunction = val => 2 Object.prototype.toString.call(val) === '[object AsyncFunction]'; 3 4isAsyncFunction(function() {}); // false 5isAsyncFunction(async function() {}); // true 6 7// 类型为 AsyncFunction,类似的还要检查是否为 Promise 8 9const isPromiseLike = obj => 10 obj !== null && 11 (typeof obj === 'object' || typeof obj === 'function') && 12 typeof obj.then === 'function'; 13 14isPromiseLike({ 15 then: function() { 16 return ''; 17 } 18}); // true 19isPromiseLike(null); // false 20isPromiseLike({}); // false

判断当前页面是否可见

1const isBrowserTabFocused = () => !document.hidden; 2 3isBrowserTabFocused(); // true 4// 更多依赖 Page Visibility 这个API吧,权当了解下

检查值是否是有下铺的JSON

1const isValidJSON = str => { 2 try { 3 JSON.parse(str); 4 return true; 5 } catch (e) { 6 return false; 7 } 8}; 9// 之前同时事也问过此问题,当时确定没想到可以 try catch 的方式来判断 10 11isValidJSON('{"name":"Adam","age":20}'); // true 12isValidJSON('{"name":"Adam",age:"20"}'); // false 13isValidJSON(null); // true

实现一个 findIndex

1const linearSearch = (arr, item) => { 2 for (const i in arr) { 3 if (arr[i] === item) return +i; 4 } 5 return -1; 6}; 7 8linearSearch([2, 9, 9], 9); // 1 9linearSearch([2, 9, 9], 7); // -1

实现事件一次绑定

1// 这个是运用添加事件参数实现的 2const listenOnce = (el, evt, fn) => 3 el.addEventListener(evt, fn, { once: true }); 4 // 可以传入 option(对象) 也可以传入 useCapture(布尔) 5 6listenOnce( 7 document.getElementById('my-id'), 8 'click', 9 () => console.log('Hello world') 10); 11// 通过闭包函数实现 12const once = fn => { 13 let called = false; 14 return function(...args) { 15 if (called) return; 16 called = true; 17 return fn.apply(this, args); 18 }; 19}; 20 21const startApp = function(event) { 22 console.log(this, event); // document.body, MouseEvent 23}; 24document.body.addEventListener('click', once(startApp)); 25 26// 现在多数框架也有对应实现,比如 VUE @click.once,起初并未运用,也没想过实现原理,现在知道了,好像也不难实现 哈哈

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

1const memoize = fn => { 2 const cache = new Map(); 3 const cached = function (val) { 4 return cache.has(val) 5 ? cache.get(val) 6 : cache.set(val, fn.call(this, val)) && cache.get(val); 7 // && 返回cache.get(val),如果是比较,&&的才返回布尔值 8 }; 9 cached.cache = cache; 10 return cached; 11}; 12 13// See the `anagrams` snippet. 14const anagramsCached = memoize(anagrams); 15anagramsCached('javascript'); // takes a long time 16anagramsCached('javascript'); // returns virtually instantly since it's cached 17console.log(anagramsCached.cache); // The cached anagrams map

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

1// Object.entries 直接将对象转为 数组形式的 key-value 2const objectToQueryString = queryParameters => { 3 return queryParameters 4 ? Object.entries(queryParameters).reduce( 5 (queryString, [key, val], index) => { 6 const symbol = queryString.length === 0 ? '?' : '&'; 7 queryString += 8 typeof val === 'string' ? `${symbol}${key}=${val}` : ''; 9 return queryString; 10 }, 11 '' 12 ) 13 : ''; 14}; 15objectToQueryString({ page: '1', size: '2kg', key: undefined }); 16// '?page=1&size=2kg'
点赞
收藏

评论区

加载中...

相关推荐

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

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

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

DF系列1、防抖函数,限制高频触发jsconstdebounce(fn,ms0)lettimeoutId;returnfunction(...args)clearTimeout(timeoutId);timeoutIdsetTimeout(()fn.apply(this,args),ms);