专栏名称: 前端大全
分享 Web 前端相关的技术文章、工具资源、精选课程、热点资讯
目录
相关文章推荐
前端早读课  ·  【第3452期】React 开发中使用开闭原则 ·  6 小时前  
启四说  ·  启四VIP策略网站,有哪些功能?如何使用? ·  17 小时前  
启四说  ·  启四VIP策略网站,有哪些功能?如何使用? ·  17 小时前  
前端早读课  ·  【第3451期】前端 TypeError ... ·  昨天  
江苏司法行政在线  ·  宿迁司法行政人、江苏监狱戒毒民警,给您拜年啦! ·  3 天前  
江苏司法行政在线  ·  宿迁司法行政人、江苏监狱戒毒民警,给您拜年啦! ·  3 天前  
51好读  ›  专栏  ›  前端大全

30+ 个工作中常用到的前端小知识(干货)

前端大全  · 公众号  · 前端  · 2024-09-27 11:50

正文

作者:隐冬

https://juejin.cn/post/6908698827033837575


1. JS为什么单线程

一个简单的原因就是, js 在设计之初只是进行一些简单的表单校验,这完全不需要多线程,单线程完全可以胜任这项工作。即便后来前端发展迅速,承载的能力越来越多,也没有发展到非多线程不可的程度。

而且还有一个主要的原因,设想一下,如果 js 是多线程的,在运行时多个线程同时对 DOM 元素进行操作,那具体以哪个线程为主就是个问题了,线程的调度问题是一个比较复杂的问题。

HTML5 新的标准中允许使用 new Worker 的方式来开启一个新的线程,去运行一段单独的 js 文件脚本,但是在这个新线程中严格的要求了可以使用的功能,比如说他只能使用 ECMAScript , 不能访问 DOM BOM 。这也就限制死了多个线程同时操作 DOM 元素的可能。

2.使用css写出一个三角形角标

元素宽高设置为 0 ,通过 border 属性来设置,让其它三个方向的 border 颜色为透明或者和背景色保持一致,剩余一条 border 的颜色设置为需要的颜色。

div {
    width0;
    height0;
    border5px solid #transparent;
    border-top-color: red;
}

3.水平垂直居中

我一般只使用两种方式 定位 或者 flex ,我觉得够用了。

div {
    width100px;
    height100px;
    position: absolute;
    top0;
    right0;
    bottom0;
    left0;
    margin: auto;
}

父级控制子集居中

.parent {
    display: flex;
    justify-content: center;
    align-items: center;
}

4. css一行文本超出...

overflowhidden;
text-overflow:ellipsis;
white-spacenowrap;

5.多行文本超出显示...

display-webkit-box;
-webkit-box-orientvertical;
-webkit-line-clamp: 3;
overflowhidden;

6.IOS手机容器滚动条滑动不流畅

overflowauto;
-webkit-overflow-scrollingtouch;

7.修改滚动条样式

隐藏 div 元素的滚动条

div::-webkit-scrollbar {
    display: none;
}

div::-webkit-scrollbar 滚动条整体部分

div::-webkit-scrollbar-thumb 滚动条里面的小方块,能向上向下移动(或往左往右移动,取决于是垂直滚动条还是水平滚动条)

div::-webkit-scrollbar-track 滚动条的轨道

div::-webkit-scrollbar-button 滚动条的轨道的两端按钮,允许通过点击微调小方块的位置。

div::-webkit-scrollbar-track-piece 内层轨道,滚动条中间部分

div::-webkit-scrollbar-corner 边角,即两个滚动条的交汇处

div::-webkit-resizer 两个滚动条的交汇处上用于通过拖动调整元素大小的小控件

注意此方案有兼容性问题,一般需要隐藏滚动条时我都是用一个色块通过定位盖上去,或者将子级元素调大,父级元素使用overflow-hidden截掉滚动条部分。暴力且直接。

8.解决ios audio无法自动播放、循环播放的问题

ios 手机在使用 audio 或者 video 播放的时候,个别机型无法实现自动播放,可使用下面的代码 hack

// 解决ios audio无法自动播放、循环播放的问题
var music = document.getElementById('video');
var state = 0;

document.addEventListener('touchstart'function(){
    if(state==0){
        music.play();
        state=1;
    }
}, false);

document.addEventListener('WeixinJSBridgeReady'function () {
    music.play();
}, false);

//循环播放
music.onended = function () {
    music.load();
    music.play();
}

9.隐藏页面元素

display-none: 元素不会占用空间,在页面中不显示,子元素也不会显示。

opacity-0: 元素透明度将为 0 ,但元素仍然存在,绑定的事件仍旧有效仍可触发执行。

visibility-hidden:元素隐藏,但元素仍旧存在,占用空间,页面中无法触发该元素的事件。

10.前端工程化

一提到前端工程化很多人想到的都是 webpack ,这是不对的, webpack 仅仅是前端工程化中的一环。在整个工程化过程中他帮我们解决了绝大多数的问题,但并没有解决所有问题。

前端工程化是通过工具提升效率,降低成本的一种手段。

近些年被广泛的关注和探讨,究其原因主要是因为现代化前端应用功能要求不断提高,业务逻辑日益复杂,作为当下互联网时代唯一不可或缺的技术,前端可以说是占据了整个开发行业的半壁江山。从传统的网站,到现在的 H5 ,移动 App ,桌面应用,以及小程序。前端技术几乎是无所不能的全面覆盖。

在这些表象的背后呢,实际上是行业对开发人员的要求发生了天翻地覆的变化,以往前端写demo,套模板,调页面这种刀耕火种的方式已经完全不符合当下对开发效率的要求,前端工程化就是在这样一个背景下被提上台面,成为前端工程师必备的手段之一。

一般来说前端工程包含,项目初始化,项目开发,提交,构建,部署,测试,监控等流程。工程化就是以工程的角度来解决这些问题。比如项目初始化我们一般使用 npm init , 创建页面模板使用 plop ,我们喜欢使用 ES6+ 开发,但是需要通过 babel 编码成 ES5 ,持续集成的时候我们使用 git/ci cd ,但是为了保持开发规范我们引入了 ESLint ,部署一般使用 git/cd 或者 jenkins 等等。

11.contenteditable

html 中大部分标签都是不可以编辑的,但是添加了 contenteditable 属性之后,标签会变成可编辑状态。

<div contenteditable='true'>div>

不过通过这个属性把标签变为可编辑状态后只有 input 事件,没有 change 事件。也不能像表单一样通过 maxlength 控制最大长度。我也忘记我在什么情况下用到过了,后面想起来再补吧。

12.calc

这是一个 css 属性,我一般称之为 css 表达式。可以计算 css 的值。最有趣的是他可以计算不同单位的差值。很好用的一个功能,缺点是不容易阅读。接盘侠没办法一眼看出 20px 是啥。

div {
    widthcalc(25% - 20px);
}

13.Date对象

获取当前时间毫秒值

// 方式一
Date.now(); // 1606381881650
// 方式二
new Date() - 0// 1606381881650
// 方式三
new Date().getTime() // 1606381881650

创建 Date 对象的兼容性问题。

// window和安卓支持,ios和mac不支持
new Date('2020-11-26'); 
// window和安卓支持,ios和mac支持
new Date('2020/11/26');

14.Proxy和Object.defineProperty区别

Proxy 的意思是代理,我一般叫他拦截器,可以拦截对象上的一个操作。用法如下,通过 new 的方式创建对象,第一个参数是被拦截的对象,第二个参数是对象操作的描述。实例化后返回一个新的对象,当我们对这个新的对象进行操作时就会调用我们描述中对应的方法。

new Proxy(target, {
    get(target, property) {

    },
    set(target, property) {

    },
    deleteProperty(target, property) {

    }
})

Proxy 区别于 Object.definedProperty

Object.defineProperty 只能监听到属性的读写,而 Proxy 除读写外还可以监听属性的删除,方法的调用等。

通常情况下我们想要监视数组的变化,基本要依靠重写数组方法的方式实现,这也是 Vue 的实现方式,而 Proxy 可以直接监视数组的变化。

const list = [123];
const listproxy = new Proxy(list, {
    set(target, property, value) {
        target[property] = value;
        return true// 标识设置成功
    }
});

list.push(4);

Proxy 是以非入侵的方式监管了对象的读写,而 defineProperty 需要按特定的方式定义对象的属性。

15.Reflect

他是 ES2015 新增的对象,纯静态对象也就是不能被实例画,只能通过静态方法的方式调用,和 Math 对象类似,只能类似 Math.random() 的方式调用。

Reflect 内部封装了一系列对对象的底层操作,一共 14 个,其中 1 个被废弃,还剩下 13 个。

Reflect 的静态方法和 Proxy 描述中的方法完全一致。也就是说 Reflect 成员方法就是 Proxy 处理对象的默认实现。

Proxy 对象默认的方法就是调用了 Reflect 内部的处理逻辑,也就是如果我们调用 get 方法,那么在内部, Reflect 就是将 get 原封不动的交给了 Reflect ,如下。

const proxy = new Proxy(obj, {
    get(target, property) {
        return Reflect.get(target, property);
    }
})

Reflect Proxy 没有绝对的关系,我们一般将他们两个放在一起讲是为了方便对二者的理解。

那为什么会有 Reflect 对象呢,其实他最大的用处就是提供了一套统一操作 Object API

判断对象是否存在某一个属性,可以使用 in 操作符,但是不够优雅,还可以使用 Reflect.has(obj, name) ; 删除一个属性可以使用 delete ,也可以使用 Reflect.deleteProperty(obj, name) ; 获取所有属性名可以使用 Object.keys , 也可以使用 Reflect.ownKeys(obj) ; 我们更推荐使用 Reflect API 来操作对象,因为他才是未来。

16.解析get参数

通过 replace 方法获取 url 中的参数键值对,可以快速解析 get 参数。

const q = {};
location.search.replace(/([^?&=]+)=([^&]+)/g,(_,k,v)=>q[k]=v);
console.log(q); 

17.解析连接url

可以通过创建 a 标签,给 a 标签赋值 href 属性的方式,获取 到协议 pathname origin location 对象上的属性。

// 创建a标签
const aEle = document.createElement('a');
// 给a标签赋值href路径
aEle.href = '/test.html';
// 访问aEle中的属性
aEle.protocol; // 获取协议
aEle.pathname; // 获取path
aEle.origin;
aEle.host;
aEle.search;
...

18.localStorage

localStorage H5 提供的永久存储空间,一般最大可存储 5M 数据,并且支持跨域隔离,他的出现极大提高了前端开发的可能性。 localStorage 的使用很多人都知道 setItem getItem , removeItem , 但他也可以直接以成员的方式操作。

// 存储
localStorage.name = 'yd';
// 获取
localStorage.name; // yd
// 删除
delete localStorage.name;
// 清除全部
localStorage.clear();

// 遍历
for (let i = 0; i     const key = localStorage.key(i); // 获取本地存储的Key
    localStorage[key]; // 获取本地存储的value
}

localStorage 满了的情况下仍继续存储并不会覆盖其他的值,而是直接报错( QuotaExceededError ),并且当前存储的值也会被清空。浏览器支持每个域名下存储 5M 数据。

19.sessionStorage

sessionStorage localStorage 的区别是,存在当前会话,很多人理解的是浏览器关闭,这是不对的,假设你在 A 页面存储了 sessionStorage ,新开选项卡将 A 页面的链接粘贴进去打开页面, sessionStorage 也是不存在的。

所以 sessionStorage 存在的条件是页面间的跳转, A 页面存储了 sessionStorage ,他要通过 超链接 或者 location.href 或者 window.open 来打开另一个同域页面才能访问 sessionStorage

这一点在混合开发嵌套 H5 的开发模式中尤为重要,如果以新开 webview 的方式打开页面,很可能 sessionStorage 就没有了。

20.会话cookie

cookie 在设置的时候如果不设置过期时间,就表示是个会话 cookie ,以前我以为关闭浏览器会话 cookie 就消失了,然而...喜提 bug 一个。

在多数情况下 windows 系统或者安卓系统确实是这样的。但是在 macOS 系统或者 ios 系统中,关闭浏览器并不会清除掉会话 cookie ,结束浏览器进程才行。

21.标签模板字符串

模板字符串支持在前面添加一个函数,第一个参数是一个有固定内容组成的数组,后面参数依次为传入的变量,函数返回值为模板字符串真正展示的值。不过这个功能个人感觉没啥用。

const tag = (params, ...args) => {
    return params[0] + args[0]; // 返回值为模板字符串的真实值。
}

const str = tag`hello ${'world'}`;

22.字符串常用的几个方法

1. includes();

字符串中是否包含某个字符串,这个不说了,其实就是 indexOf 的替代方案,用起来更优雅,

2. startsWith();

字符串是否为某个字符串开始,我一般用它判断 url 是否有 http

3. endsWith();

字符串是否为某个字符串结尾。判断后缀名的时候尤其有效。

4. repeat(number);

得到一个重复 number 次的字符串。额...我也不知道什么时候有用,一般我用它造测试数据。

5. 'abc'.padEnd(5, '1'); // abc11;

用给定的字符串在尾部拼接到指定长度,第一个参数为长度,第二个参数为用于拼接的值。

6. 'abc'.padStart(5, '1'); // 11abc;

用给定的字符串在首部拼接到指定长度第一个参数为长度,第二个参数为用于拼接的值。首部补0?

23.数组快速去重

应该很多人都知道这个,数组转换成 Set , 再转换为数组,不过这种去重方式只能去除基本数据类型组成的数组。

const arr = [123456];

const arr2 = new Set(arr);

const arr3 = [...arr2];

24.Object.keys, values, entries

一般我们常用 Object.keys ,返回一个对象的键组成的数组,其实还有 Object.values ,返回对象值组成的数组, Object.entries 将对象转成数组,每个元素是键值对组成的数组,可以使用此功能快速将对象转为 Map


const obj = {name'yd'age18};

Object.keys(obj); // ['name', 'age'];

Object.values(obj); // ['yd', 18];

const l = Object.entries(obj); // [['name', 'yd'], ['age': 18]];

const m = new Map(l);

25.Object.getOwnPropertyDescriptors

获取对象的描述信息

Object.assign 复制时,将对象的属性和方法当做普通属性来复制,并不会复制完整的描述信息,比如 this

const p1 = {
    a'y',
    b'd',
    get name() {
        return `${this.a} ${this.b}`;
    }
}
const p2 = Object.assign({}, p1);

p2.a = 'z';

p2.name; // y d; 发现并没有修改p2.a的值,是因为this仍旧指向p1

使用 Object.getOwnPropertyDescriptors 获取完整描述信息

const description = Object.getOwnPropertyDescriptors(p1);

const p2 = Object.defineProperty({}, description);

p2.a = 'z';

p2.name; // z d

26.BigInt

JavaScript 可以处理的最大数字是 2 53 次方 - 1 ,这一点我们可以在 Number.MAX_SAFE_INTEGER 中看到。

consoel.log(Number.MAX_SAFE_INTEGER); //9007199254740991

更大的数字则无法处理, ECMAScript2020 引入 BigInt 数据类型来解决这个问题。通过把字母 n 放在末尾, 可以运算大数据。

BigInt 可以使用算数运算符进行加、减、乘、除、余数及幂等运算。它可以由数字和十六进制或二进制字符串构造。此外它还支持 AND OR NOT XOR 之类的按位运算。唯一无效的位运算是零填充右移运算符。

const bigNum = 100000000000000000000000000000n;
console.log(bigNum * 2n); // 200000000000000000000000000000n

const bigInt = BigInt(1);
console.log(bigInt); // 1n;

const bigInt2 = BigInt('2222222222222222222');
console.log(bigInt2); // 2222222222222222222n;

BigInt是一个大整数,所以他不能用来存储小数。

27.??合并空运算符







请到「今天看啥」查看全文