24个解决实际问题的ES6代码片段(小结)


Posted in Javascript onFebruary 02, 2020

这是从30 seconds of code中挑出来的非常有用的一些代码片段,这是一个非常棒的项目,大家可以去github上去搜索一下,给个star。

在本文中,我试图根据它们的实际用途对它们进行分类,回答您在项目中可能遇到的常见问题:

1.如何隐藏指定的所有元素?

const hide = (...el) => [...el].forEach(e => (e.style.display = 'none'));

// Example
hide(document.querySelectorAll('img')); // Hides all <img> elements on the page

2.如何检查元素是否具有指定的类?

const hasClass = (el, className) => el.classList.contains(className);

// Example
hasClass(document.querySelector('p.special'), 'special'); // true

3.如何为元素切换类?

const toggleClass = (el, className) => el.classList.toggle(className);

// Example
toggleClass(document.querySelector('p.special'), 'special'); 
// The paragraph will not have the 'special' class anymore

这里使用了classList.toggle()方法

toggle( String [, force] )

当只有一个参数时:切换类值;也就是说,即如果类值存在,则删除它并返回 false,如果不存在,则添加它并返回 true。
当存在第二个参数时:若第二个参数的执行结果为 true,则添加指定的类值,若执行结果为 false,则删除它。

4.如何获取当前页面的滚动位置?

const getScrollPosition = (el = window) => ({
 x: el.pageXOffset !== undefined ? el.pageXOffset : el.scrollLeft,
 y: el.pageYOffset !== undefined ? el.pageYOffset : el.scrollTop
});

// Example
getScrollPosition(); // {x: 0, y: 200}

5.如何平滑滚动到页面顶部?

const scrollToTop = () => {
 const c = document.documentElement.scrollTop || document.body.scrollTop;
 if (c > 0) {
 window.requestAnimationFrame(scrollToTop);
 window.scrollTo(0, c - c / 8);
 }
};

// Example
scrollToTop();

递归的方法不断调用使用scrollToTop(),requestAnimationFrame方法告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。它的回调函数执行次数通常与浏览器屏幕刷新次数相匹配,所以效果会比较平滑。

获取当前页面滚动条纵坐标的位置:document.body.scrollTop与document.documentElement.scrollTop

获取当前页面滚动条横坐标的位置:document.body.scrollLeft与document.documentElement.scrollLeft

6.如何检查父元素是否包含子元素?

const elementContains = (parent, child) => parent !== child && parent.contains(child);

// Examples
elementContains(document.querySelector('head'), document.querySelector('title')); 
// true
elementContains(document.querySelector('body'), document.querySelector('body')); // false

7.如何检查指定的元素在视口中是否可见?

const elementIsVisibleInViewport = (el, partiallyVisible = false) => {
 const { top, left, bottom, right } = el.getBoundingClientRect();
 const { innerHeight, innerWidth } = window;
 return partiallyVisible
 ? ((top > 0 && top < innerHeight) || (bottom > 0 && bottom < innerHeight)) &&
  ((left > 0 && left < innerWidth) || (right > 0 && right < innerWidth))
 : top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth;
};

// Examples
elementIsVisibleInViewport(el); // (not fully visible)
elementIsVisibleInViewport(el, true); // (partially visible)

传入partiallyVisible参数,区分判断是是部分可见还是全部可见。

Element.getBoundingClientRect()方法返回元素的大小及其相对于视口的位置。

8.如何获取元素中的所有图像?

const getImages = (el, includeDuplicates = false) => {
 const images = [...el.getElementsByTagName('img')].map(img => img.getAttribute('src'));
 return includeDuplicates ? images : [...new Set(images)];
};

// Examples
getImages(document, true); // ['image1.jpg', 'image2.png', 'image1.png', '...']
getImages(document, false); // ['image1.jpg', 'image2.png', '...']

9.如何确定设备是移动设备还是台式机/笔记本电脑?

const detectDeviceType = () =>
 /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
 ? 'Mobile'
 : 'Desktop';

// Example
detectDeviceType(); // "Mobile" or "Desktop"

10.如何获取当前URL

const currentURL = () => window.location.href;

// Example
currentURL(); // 'https://google.com'

11.如何创建包含当前URL参数的对象?

const getURLParameters = url =>
 (url.match(/([^?=&]+)(=([^&]*))/g) || []).reduce(
 (a, v) => ((a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1)), a),
 {}
 );

// Examples
getURLParameters('http://url.com/page?n=Adam&s=Smith'); // {n: 'Adam', s: 'Smith'}
getURLParameters('google.com'); // {}

12.如何将一组表单元素编码为对象?

const formToObject = form =>
 Array.from(new FormData(form)).reduce(
 (acc, [key, value]) => ({
  ...acc,
  [key]: value
 }),
 {}
 );

// Example
formToObject(document.querySelector('#form')); // { email: 'test@email.com', name: 'Test Name' }

Array.from方法用于将两类对象转为真正的数组。类似数组的对象(array-like object)和可遍历(iterable)的对象(包括 ES6 新增的数据结构 Set 和 Map)。
reducer 函数接收4个参数:

  • Accumulator (acc) (累计器)
  • Current Value (cur) (当前值)
  • Current Index (idx) (当前索引)
  • Source Array (src) (源数组)

13.如何从对象中检索出给定的一组属性?

const get = (from, ...selectors) =>
 [...selectors].map(s =>
 s
  .replace(/\[([^\[\]]*)\]/g, '.$1.')
  .split('.')
  .filter(t => t !== '')
  .reduce((prev, cur) => prev && prev[cur], from)
 );
const obj = { selector: { to: { val: 'val to select' } }, target: [1, 2, { a: 'test' }] };

// Example
get(obj, 'selector.to.val', 'target[0]', 'target[2].a'); // ['val to select', 1, 'test']

14.延迟调用提供的函数(以毫秒为单位)

const delay = (fn, wait, ...args) => setTimeout(fn, wait, ...args);
delay(
 function(text) {
 console.log(text);
 },
 1000,
 'later'
); 

// Logs 'later' after one second.

15.如何在给定元素上触发特定事件,并可选地传递自定义数据?

const triggerEvent = (el, eventType, detail) =>
 el.dispatchEvent(new CustomEvent(eventType, { detail }));

// Examples
triggerEvent(document.getElementById('myId'), 'click');
triggerEvent(document.getElementById('myId'), 'click', { username: 'bob' });

构造方法 CustomerEvent() 创建一个新的 CustomEvent 对象。
CustomEvent 事件是由程序创建的,可以有任意自定义功能的事件。

16.如何从元素中移除事件侦听器?

const off = (el, evt, fn, opts = false) => el.removeEventListener(evt, fn, opts);

const fn = () => console.log('!');
document.body.addEventListener('click', fn);
off(document.body, 'click', fn); // no longer logs '!' upon clicking on the page

17.将给定的毫秒数转换为可读格式

const formatDuration = ms => {
 if (ms < 0) ms = -ms;
 const time = {
 day: Math.floor(ms / 86400000),
 hour: Math.floor(ms / 3600000) % 24,
 minute: Math.floor(ms / 60000) % 60,
 second: Math.floor(ms / 1000) % 60,
 millisecond: Math.floor(ms) % 1000
 };
 return Object.entries(time)
 .filter(val => val[1] !== 0)
 .map(([key, val]) => `${val} ${key}${val !== 1 ? 's' : ''}`)
 .join(', ');
};

// Examples
formatDuration(1001); // '1 second, 1 millisecond'
formatDuration(34325055574); // '397 days, 6 hours, 44 minutes, 15 seconds, 574 milliseconds'

18.如何得到两个日期之间的差异(以天为单位)

const getDaysDiffBetweenDates = (dateInitial, dateFinal) =>
 (dateFinal - dateInitial) / (1000 * 3600 * 24);

// Example
getDaysDiffBetweenDates(new Date('2017-12-13'), new Date('2017-12-22')); // 9

19.如何对传递的URL发出GET请求

const httpGet = (url, callback, err = console.error) => {
 const request = new XMLHttpRequest();
 request.open('GET', url, true);
 request.onload = () => callback(request.responseText);
 request.onerror = () => err(request);
 request.send();
};

httpGet(
 'https://jsonplaceholder.typicode.com/posts/1',
 console.log
); 

// Logs: {"userId": 1, "id": 1, "title": "sample title", "body": "my text"}

20.如何对传递的URL发出POST请求?

const httpPost = (url, data, callback, err = console.error) => {
 const request = new XMLHttpRequest();
 request.open('POST', url, true);
 request.setRequestHeader('Content-type', 'application/json; charset=utf-8');
 request.onload = () => callback(request.responseText);
 request.onerror = () => err(request);
 request.send(data);
};

const newPost = {
 userId: 1,
 id: 1337,
 title: 'Foo',
 body: 'bar bar bar'
};
const data = JSON.stringify(newPost);
httpPost(
 'https://jsonplaceholder.typicode.com/posts',
 data,
 console.log
); 

// Logs: {"userId": 1, "id": 1337, "title": "Foo", "body": "bar bar bar"}

21. 如何为指定的选择器创建具有指定范围、步骤和持续时间的计数器?

const counter = (selector, start, end, step = 1, duration = 2000) => {
 let current = start,
 _step = (end - start) * step < 0 ? -step : step,
 timer = setInterval(() => {
  current += _step;
  document.querySelector(selector).innerHTML = current;
  if (current >= end) document.querySelector(selector).innerHTML = end;
  if (current >= end) clearInterval(timer);
 }, Math.abs(Math.floor(duration / (end - start))));
 return timer;
};

// Example
counter('#my-id', 1, 1000, 5, 2000); // Creates a 2-second timer for the element with id="my-id"

22.如何将字符串复制到剪贴板

const copyToClipboard = str => {
 const el = document.createElement('textarea');
 el.value = str;
 el.setAttribute('readonly', '');
 el.style.position = 'absolute';
 el.style.left = '-9999px';
 document.body.appendChild(el);
 const selected =
 document.getSelection().rangeCount > 0 ? document.getSelection().getRangeAt(0) : false;
 el.select();
 document.execCommand('copy');
 document.body.removeChild(el);
 if (selected) {
 document.getSelection().removeAllRanges();
 document.getSelection().addRange(selected);
 }
};

// Example
copyToClipboard('Lorem ipsum'); // 'Lorem ipsum' copied to clipboard.

document.getSelection()返回一个  Selection 对象,表示用户选择的文本范围或光标的当前位置。

23.判断页面的浏览器选项卡是否聚焦

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

// Example
isBrowserTabFocused(); // true

24.如果不存在目录,则如何创建

const fs = require('fs');
const createDirIfNotExists = dir => (!fs.existsSync(dir) ? fs.mkdirSync(dir) : undefined);

// Example
createDirIfNotExists('test'); // creates the directory

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript 解析后的xml对象的读取方法细解
Jul 25 Javascript
js加强的经典分页实例
Mar 15 Javascript
基于OO的动画附加插件,可以实现弹跳、渐隐等动画效果 分享
Jun 24 Javascript
js 数组去重的四种实用方法
Sep 09 Javascript
JavaScript中的类数组对象介绍
Dec 30 Javascript
jquery实现的树形目录实例
Jun 26 Javascript
黑帽seo劫持程序,js劫持搜索引擎代码
Sep 15 Javascript
AngularJS中控制器函数的定义与使用方法示例
Oct 10 Javascript
JS+HTML5 canvas绘制验证码示例
Dec 05 Javascript
Vue指令v-for遍历输出JavaScript数组及json对象的常见方式小结
Feb 11 Javascript
javaScript中indexOf用法技巧
Nov 26 Javascript
vue 自定义的组件绑定点击事件
Apr 21 Vue.js
浅谈vuex为什么不建议在action中修改state
Feb 02 #Javascript
vuex+axios+element-ui实现页面请求loading操作示例
Feb 02 #Javascript
vue实现的封装全局filter并统一管理操作示例
Feb 02 #Javascript
node 版本切换的实现
Feb 02 #Javascript
vue路由缓存的几种实现方式小结
Feb 02 #Javascript
vue简单封装axios插件和接口的统一管理操作示例
Feb 02 #Javascript
vue实现路由不变的情况下,刷新页面操作示例
Feb 02 #Javascript
You might like
比特率,大家看看这个就不用收音机音质去比MP3音质了
2021/03/01 无线电
PHP脚本的10个技巧(5)
2006/10/09 PHP
PHP警告Cannot use a scalar value as an array的解决方法
2012/01/11 PHP
对象失去焦点时自己动提交数据的实现代码
2012/11/06 PHP
Yii使用技巧大汇总
2015/12/29 PHP
PHP实现基于mysqli的Model基类完整实例
2016/04/08 PHP
php微信开发之自定义菜单完整流程
2016/10/08 PHP
通用javascript脚本函数库 方便开发
2009/10/13 Javascript
jQuery的运行机制和设计理念分析
2011/04/05 Javascript
jquery利用ajax调用后台方法实例
2013/08/23 Javascript
js隐式全局变量造成的bug示例代码
2014/04/22 Javascript
jquery插件jquery.beforeafter.js实现左右拖拽分隔条对比图片的方法
2015/08/07 Javascript
一种Javascript解释ajax返回的json的好方法(推荐)
2016/06/02 Javascript
layer弹出层全屏及关闭方法
2018/08/17 Javascript
Vue实现调节窗口大小时触发事件动态调节更新组件尺寸的方法
2018/09/15 Javascript
Javascript实现秒表倒计时功能
2018/11/17 Javascript
jQuery实现当拉动滚动条到底部加载数据的方法分析
2019/01/24 jQuery
nodejs如何在package.json中设置多条启动命令
2020/03/16 NodeJs
vue相同路由跳转强制刷新该路由组件操作
2020/08/05 Javascript
python自动zip压缩目录的方法
2015/06/28 Python
python 实现网上商城,转账,存取款等功能的信用卡系统
2016/07/15 Python
python实现NB-IoT模块远程控制
2018/06/20 Python
Python 面向对象静态方法、类方法、属性方法知识点小结
2020/03/09 Python
python给视频添加背景音乐并改变音量的具体方法
2020/07/19 Python
HTML5 对各个标签的定义与规定:body的介绍
2012/06/21 HTML / CSS
HTML中使用SVG与SVG预定义形状元素介绍
2013/06/28 HTML / CSS
链表面试题-一个链表的结点结构
2015/05/04 面试题
介绍下static、final、abstract区别
2015/01/30 面试题
新学期班主任寄语
2014/01/18 职场文书
2014年乡镇植树节活动方案
2014/02/28 职场文书
美容院经理岗位职责
2014/04/03 职场文书
巾帼文明岗申报材料
2014/05/01 职场文书
2014年司法所工作总结
2014/11/22 职场文书
培训通知
2015/04/17 职场文书
2016年小学生清明节广播稿
2015/12/17 职场文书
JS一分钟在github+Jekyll的博客中添加访问量功能的实现
2021/04/03 Javascript