分类 前端开发 下的文章

  • 如何隐藏所有指定的元素:
const hide = (el) => Array.from(el).forEach(e => (e.style.display = 'none'));

// 事例:隐藏页面上所有`<img>`元素?
hide(document.querySelectorAll('img'))
  • 如何检查元素是否具有指定的类 ?

页面DOM里的每个节点上都有一个 classList 对象,程序员可以使用里面的方法新增、删除、修改节点上的CSS类;使用 classList,程序员还可以用它来判断某个节点是否被赋予了某个CSS类;

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

// 事例
hasClass(document.querySelector('p.special'), 'special') // true
  • 如何切换一个元素的类 ?
const toggleClass = (el, className) => el.classList.toggle(className)

// 事例 移除 p 具有类`special`的 special 类
toggleClass(document.querySelector('p.special'), 'special')

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

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

// 事例
getScrollPosition(); // {x: 0, y: 200}
  • 如何平滑滚动到页面顶部?
const scrollToTop = () => {
         const c = document.documentElement.scrollTop || document.body.scrollTop;
  if (c > 0) {
    window.requestAnimationFrame(scrollToTop);
    window.scrollTo(0, c - c / 8);
  }
}

window.requestAnimationFrame() 告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行。
requestAnimationFrame:优势:由系统决定回调函数的执行时机。60Hz的刷新频率,那么每次刷新的间隔中会执行一次回调函数,不会引起丢帧,不会卡顿。

  • 如何检查父元素是否包含子元素 ?
const elementContains = (parent, child) => parent !== child && parent.contains(child);

// 事例
elementContains(document.querySelector('head'), document.querySelector('title')); 
// true
elementContains(document.querySelector('body'), document.querySelector('body')); 
// false
  • 如何检查指定的元素在视口中是否可见 ?
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;
};

// 事例
elementIsVisibleInViewport(el); // 需要左右可见
elementIsVisibleInViewport(el, true); // 需要全屏(上下左右)可以见
  • 如何获取元素中的所有图像 ?
const getImages = (el, includeDuplicates = false) => {
  const images = [...el.getElementsByTagName('img')].map(img => img.getAttribute('src'));
  return includeDuplicates ? images : [...new Set(images)];
};

// 事例:includeDuplicates 为 true 表示需要排除重复元素
getImages(document, true); // ['image1.jpg', 'image2.png', 'image1.png', '...']
getImages(document, false); // ['image1.jpg', 'image2.png', '...']
  • 如何确定设备是移动设备还是台式机/笔记本电脑 ?
 const detectDeviceType = () =>
  /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
    ? 'Mobile'
    : 'Desktop';

// 事例
detectDeviceType(); // "Mobile" or "Desktop"
  • How to get the current URL ?
const currentURL = () => window.location.href

// 事例
currentURL() // 'https://google.com'
  • 如何创建一个包含当前URL参数的对象 ?
const getURLParameters = url =>
  (url.match(/([^?=&]+)(=([^&]*))/g) || []).reduce(
    (a, v) => ((a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1)), a),
    {}
  );

// 事例
getURLParameters('http://url.com/page?n=Adam&s=Smith'); // {n: 'Adam', s: 'Smith'}
getURLParameters('google.com'); // {}
  • 如何将一组表单子元素转化为对象 ?
const formToObject = form =>
  Array.from(new FormData(form)).reduce(
    (acc, [key, value]) => ({
      ...acc,
      [key]: value
    }),
    {}
  );

// 事例
formToObject(document.querySelector('#form')); 
// { email: 'test@email.com', name: 'Test Name' }
  • 如何从对象检索给定选择器指示的一组属性 ?
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']
  • 如何在等待指定时间后调用提供的函数 ?
const delay = (fn, wait, ...args) => setTimeout(fn, wait, ...args);
delay(
  function(text) {
    console.log(text);
  },
  1000,
  'later'
); 

// 1秒后打印 'later'
  • 如何在给定元素上触发特定事件且能选择地传递自定义数据 ?
const triggerEvent = (el, eventType, detail) =>
  el.dispatchEvent(new CustomEvent(eventType, { detail }));

// 事例
triggerEvent(document.getElementById('myId'), 'click');
triggerEvent(document.getElementById('myId'), 'click', { username: 'bob' });
  • 如何从元素中移除事件监听器 ?
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); 
  • 如何获得给定毫秒数的可读格式 ?
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(', ');
};

// 事例
formatDuration(1001); // '1 second, 1 millisecond'
formatDuration(34325055574); 
// '397 days, 6 hours, 44 minutes, 15 seconds, 574 milliseconds'
  • 如何获得两个日期之间的差异 (以天为单位) ?
const getDaysDiffBetweenDates = (dateInitial, dateFinal) =>
  (dateFinal - dateInitial) / (1000 * 3600 * 24);

// 事例
getDaysDiffBetweenDates(new Date('2017-12-13'), new Date('2017-12-22')); // 9
  • 如何向传递的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
); 

// {"userId": 1, "id": 1, "title": "sample title", "body": "my text"}
  • 如何对传递的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
); 

// {"userId": 1, "id": 1337, "title": "Foo", "body": "bar bar bar"}
  • 如何为指定选择器创建具有指定范围,步长和持续时间的计数器 ?
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;
};

// 事例
counter('#my-id', 1, 1000, 5, 2000); 
// 让 `id=“my-id”`的元素创建一个2秒计时器
  • 如何将字符串复制到剪贴板 ?
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);
  }
};

// 事例
copyToClipboard('Lorem ipsum'); 
// 'Lorem ipsum' copied to clipboard
  • 如何确定页面的浏览器选项卡是否聚焦 ?
const isBrowserTabFocused = () => !document.hidden;

// 事例
isBrowserTabFocused(); // true
  • 如何创建目录 (如果不存在) ?
const fs = require('fs');
const createDirIfNotExists = dir => (!fs.existsSync(dir) ? fs.mkdirSync(dir) : undefined);

// 事例
createDirIfNotExists('test'); 

https://blog.csdn.net/qq_26758205/article/details/107030586

让你受益匪浅的前端技术干货系列

这是一个凝聚了很多优秀前端开发者心血的精选技术干货列表,希望你能从中学习提升前端开发技术。如果觉得这个系列有收获,欢迎推荐给朋友。

一)前端基本功

前端相关的基础知识

《HTTP/3 来了 !未来可期》

《你可能已经忽略的 git commit 规范》

《手写一个 WebSocket 协议》

《5000字解析:前端五种跨平台技术》

《一篇搞定移动端适配》

《Chrome DevTools中的这些骚操作,你都知道吗?》

《Chrome 运行时性能瓶颈分析》

《当浏览器全面禁用三方 Cookie》

《无形中提高工作效率的 Chrome 插件》

《还分不清 Cookie、Session、Token、JWT?》

《你连 HTTPS 原理都不懂,还讲“中间人攻击”?》

《npm install 原理分析》

《不容错过的 Babel 7 知识汇总》

《一文搞懂 Web 中暗藏的密码学》

《解读HTTP/2与HTTP/3 的新特性》

CSS

《那些不常见,但却非常实用的 CSS 属性》

《面试官:你可以用纯 CSS 判断鼠标进入的方向吗?》

《二营长,快掏个CSS出来给我画个井字棋游戏》

《CSS 故障艺术》

《我写CSS的常用套路(附demo的效果实现与源码)》

《来自新时代的 CSS》

《你还不会 CSS 动画?》

JavaScript

《谁说前端不需要懂二进制》

《你不知道的 Blob》

《Javascript常用的 60 余种工具方法》

《你可以这样优化 if-else 代码结构》

《JS 图片压缩的实现思路》

《一个简洁、有趣的无限下拉方案》

《请你实现一个大文件上传和断点续传》

《从 ES6 到 ES10 的新特性万字大总结》

《JavaScript 手写代码无敌秘籍》

TypeScript

《通俗易懂的 TypeScript 入门教程》

《用 TypeScript 编写 React 的最佳实践》

《一文读懂 JS 装饰器》

《你真的懂 Promise 吗?》

《Typescript 那些好用的技巧》

《Typescript 严格模式有多严格?》

二)前端框架、工具、库

React

《用 TypeScript 编写 React 的最佳实践》

《2020 年你应该知道的 React 库》

《5 个技巧助你编写更好的 React 代码》

《10个案例让你彻底理解React hooks的渲染逻辑》

《组件演进史:从Mixin到HOC,再到Hook》

Vue

《1.1万字从零解读Vue3.0源码响应式系统》

《重头来过的 Vue 3 带来了什么?》

Nodejs

《一杯茶的时间,上手 Node.js》

《深入理解 Node.js 进程与线程》

Deno

《Deno 会取代 Node.js 吗?》

《了不起的 Deno 入门教程》

《推倒 Node 重做,Deno 1.0 来了》

Webpack

《一文搞懂 Webpack 多入口配置》

GraphQL

《GraphQL-前端开发的利剑与桥梁》

《GraphQL 入门看这篇就够了》

《前端工程师应该了解的 GraphQL》

VS Code

《动图演示11个必备 VS Code 插件》

三)面试题精选

《高频前端面试题》
《吐血整理!再来一打 Webpack 面试题》

《前端同学经常忽视的一个 JavaScript 面试题》

《如何轻松拿到淘宝前端 offer》

《三年大厂面试官:二面题》

《十几道含答案的大厂面试题总结》

《如何答一道惊艳面试官的数组去重问题?》

《10 个 CSS 高频面试题,你都会吗?》

《经常被面试官考的 JS 数据类型知识你真的懂吗?》

《面试须知:浏览器相关原理详细总结》

《2019 大龄前端如何准备面试?》

《2018 大厂高级前端面试题汇总》

四)前端开发的职业修炼

《前端如何在项目中做出亮点》

《Facebook 前端技术栈重构分享》

《当前端基建任务落到你身上,该如何推动协作?》

《使用 docker 高效部署你的前端应用》

《关于前端学习路线的一些建议》

《各种场景唤起 App 的骚操作》

《Web 视频播放前前后后那些事》

《你必须要注意的依赖安全漏洞》

《从 12.67s 到 1.06s 的网站性能优化实战》

《网易云音乐前端性能监控实践》

《一个阿里前端工程师的成长之路》

《非常全面的前端协作规范》

《一名合格前端工程师的自检清单》

《从 0 到 1 再到 100:搭建、编写、构建一个前端项目》