- 作者:陳大魚頭
- github: KRISACHAN
如果不希望職業生涯過早結束,持續學習對於開發者來說是必不可少的。
最近《前端面試之道》的作者爲了讓一些人能在這塊地方記錄自己學習到的內容而建立起了一個學習倉庫。
倉庫地址如下:
https://github.com/KieSun/today-i-learned
這些內容通常會是一個小點,可能並不足以寫成一篇文章。但是這個知識點可能很多人也不知道,那麼通過這種記錄的方式讓別人同樣也學習到這個知識點就是一個很棒的事情了。
具體的知識點如下:
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: '[email protected]',
_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: "[email protected]", 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/today-i-learned
如果你、喜歡探討技術,或者對本文有任何的意見或建議,你可以掃描下方二維碼,關注微信公衆號“魚頭的Web海洋”,隨時與魚頭互動。歡迎!衷心希望可以遇見你。