共计 5005 个字符,预计需要花费 13 分钟才能阅读完成。
- 作者:陈大鱼头
- github:KRISACHAN
如果不希望职业生涯过早结束,持续学习对于开发者来说是必不可少的。
最近《前端面试之道》的作者为了让一些人能在这块地方记录自己学习到的内容而建立起了一个学习仓库。
仓库地址如下:
https://github.com/KieSun/tod…
这些内容通常会是一个小点,可能并不足以写成一篇文章。但是这个知识点可能很多人也不知道,那么通过这种记录的方式让别人同样也学习到这个知识点就是一个很棒的事情了。
具体的知识点如下:
CSS
CSS Houdini
我们在日常开发中可能会用到过许多 CSS IN JS
或者 CSS module
的方案,但是 JS IN CSS
,你听说过吗?
CSS Houdini 是由一群來自各个国际大厂的工程师所组成的工作小组,志在建立一系列的 API 来让开发者能够介入浏览器的 CSS 引擎中,用来解決 CSS 长久以来的问题。
例子如下:
我们首先定义一个 JS 文件叫 houdini.js
,一个 HTML 文件叫 index.html
。
houdini.js
文件内容如下:
'use strict'
registerPaint('overdraw', class {static get inputProperties() {return ['--border-width']; }
paint(ctx, geom, properties) {const borderWidth = parseInt(properties.get('--border-width'));
ctx.shadowColor = 'rgba(0,0,0,0.25)';
ctx.shadowBlur = borderWidth;
ctx.fillStyle = 'rgba(255, 255, 255, 1)';
ctx.fillRect(borderWidth,
borderWidth,
geom.width - 2 * borderWidth,
geom.height - 2 * borderWidth);
}
});
index.html
文件内容如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" />
<meta name="screen-orientation" content="portrait">
<meta name="x5-orientation" content="portrait">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
<meta http-equiv="Cache-Control" content="no-siteapp">
<title>demo</title>
<style>
.overdraw {
--border-width: 10;
border-style: solid;
border-width: calc(var(--border-width) * 1px);
border-image-source: paint(overdraw);
border-image-slice: 0 fill;
border-image-outset: calc(var(--border-width) * 1px);
width: 200px;
height: 200px;
}
</style>
</head>
<body>
<div class="overdraw"></div>
<script>
'use strict';
if (window.CSS) {CSS.paintWorklet.addModule('houdnini.js');
}
</script>
</body>
</html>
然后开个静态服务器,就可以看效果了,效果如下:
JS
另类的数组求和
let arr = [1, 2, 3, 4, 5]
eval(arr.join('+'))
数组完全展开
function myFlat(arr) {while (arr.some(t => Array.isArray(t))) {arr = ([]).concat.apply([], arr);
}
return arr;
}
var arrTest1 = [1, [2, 3, [4]], 5, 6, [7, 8], [[9, [10, 11], 12], 13], 14];
// Expected Output: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
console.log(myFlat(arrTest1))
实现 sleep 函数
function sleep(interval) {
return new Promise(resolve => {setTimeout(resolve, interval);
})
}
async function test() {for (let index = 0; index < 10; index++) {console.log(index);
await sleep(2000)
}
}
正则过滤违规词
var ma = "大傻逼".split('');
var regstr = ma.join('([^\u4e00-\u9fa5]*?)');
var str = "这是一篇文章, 需要过滤掉大傻逼这三个词, 大傻逼中间出汉字以外的字符 大_/_傻 a1v 逼和 大傻 a1v 逼";
var reg = new RegExp(regstr , 'g');
str.replace(reg,"< 替换的词 >");
Node
开启 Gzip
const express = require('express');
const compression = require('compression');
const app = express();
app.use(compression());
统计 Git 代码行数
const {exec} = require('child_process');
const {argv} = require('yargs');
const readLines = stdout => {
const stringArray = stdout
.toString()
.split(/(\n)/g)
.filter(str => str !== '\n' && str);
const dataArray = [];
stringArray.map(str => {const data = str.split(/(\t)/g).filter(str => str !== '\t');
const [newLine, deletedLine, filePath] = data;
dataArray.push({newLine, deletedLine, filePath});
});
return dataArray;
};
try {if (!argv.commit) throw new Error('')
exec(`git diff ${argv.commit} --numstat`, (error, stdout, stderr) => {console.table(readLines(stdout));
});
} catch (e) {console.log(e);
}
实现一个 only 函数
var obj = {
name: 'tobi',
last: 'holowaychuk',
email: 'tobi@learnboost.com',
_id: '12345'
};
const only = (obj, para) => {if (!obj || !para) {new Error('please check your args!') }
let newObj = {};
let newArr = Array.isArray(para) ? para : typeof (para) === 'string' ? para.split(/ +/) : [];
newArr.forEach((item) => {if (item && obj[item] && !newObj[item]) {newObj[item] = obj[item];
}
})
return newObj;
}
// {email: "tobi@learnboost.com", last: "holowaychuk", name: "tobi"}
console.log(only(obj, ['name', 'last', 'email']));
console.log(only(obj, 'name last email'));
实际业务问题
视频兼容相关
在安卓中,直接使用原生 video 会导致全屏播放,盖住所有元素,因此使用 x5 播放器。但是 x5 播放器还是存在问题,虽然不会盖住元素,但是会自己添加特效(盖一层导航栏蒙层)。
<video
className='live-detail__video vjs-big-play-centered'
id='live-player'
controls={false}
playsInline
webkit-playsinline='true'
x5-video-player-type='h5'
x5-video-orientation='portrait'
x5-playsinline='true'
style={style}
/>
这样可以在安卓下使用 x5 播放器,playsInline
及 webkit-playsinline
属性可以在 iOS 环境下启用内联播放。但是通过属性设置内联播放兼容性并不怎么好,所以这时候我们需要使用 iphone-inline-video[2] 这个库,通过 enableInlineVideo(video)
就可以了。
聊天数据渲染
考虑到直播中聊天数据频繁,因此所有接收到的数据会先存入一个数组 buffer 中,等待 2 秒后统一渲染。
// 接收到消息就先 push 到缓存数组中
this.bufferAllComments.push({
customerName: fromCustomerName,
commentId,
content,
commentType
})
// 利用定时器,每两秒将数组中的中的 concat 到当前聊天数据中并清空缓存
this.commentTimer = setInterval(() => {if (this.bufferAllComments.length) {this.appendChatData(this.bufferAllComments)
this.bufferAllComments = []}
}, 2000)
链表作为聊天数据的载体
同样考虑到直播中聊天数据频繁插入,因此使用链表来存储显示的聊天数据,目前只存储 50 条数据,这样删除前面的只要很简单。
- 使用链表的原因是考虑到频繁的去除数组头部数据去造成空间复杂度的问题
- 另外也实现了支持迭代器的功能,代码如下:
[Symbol.iterator] () {
let current = null; let target = this
return {next () {
current = current != null ? current.next : target.head
if (current != null) {return { value: current.value, done: false}
}
return {value: undefined, done: true}
},
return () {return { done: true}
}
}
}
总结
工作中建立起来的一些心得
- 要根据任务四象限划分好每天要做的事,按紧急度去完成任务(重要紧急,重要不紧急,紧急不重要,不重要不紧急);
- 学会自我总结(写周报或日志汇总所遇到的问题,时刻翻阅);
- 拥有快速定位并解决问题的能力(通过已知的条件去判断所遇到的问题);
- 要多与上下游沟通,了解团队大家所做的事以及进度(方便自己合理安排任务);
- 积极乐观不抱怨(最好可以时常给团队带来正能量,而不是满腹抱怨);
- 多运动,多休息(身体革命的本钱,没有一个好的身体就什么都做不了)。
最后
这是一个需要大家一起分享才能持续下去的事情,光靠我,YCK 或者少量几个人分享是做不下去的。欢迎大家参与到这件事情中来,地址如下:
https://github.com/KieSun/tod…
如果你、喜欢探讨技术,或者对本文有任何的意见或建议,你可以扫描下方二维码,关注微信公众号“ 鱼头的 Web 海洋 ”,随时与鱼头互动。欢迎!衷心希望可以遇见你。