又是一个练手用的
移动端弹出框滚动穿透
有两个解决方法:
-
弹窗组件最外层添加
touchmove
事件监听,并阻止默认行为,但会阻止所有滚动事件,仅当弹框内不需要滚动时使用 body
设置 position: fixed
,可能影响布局,酌情使用
移动端滑动选择(模拟:hover)
移动端原生不支持滑动触发状态,touchmove
target
pageX
、pageY
、clientX
、clientY
clientWidth
滑动事件触发频率较高,易产生性能问题,通常使用节流函数限制触发频次
元素移动性能
使用transform
translate
还可使用translate3d
移动端禁止下拉刷新
方法一
对body
overscroll-behavior: none;
方法二
使body
.body,
.wrapper {
/* 脱离文档流 */
position: absolute;
top: 0px;
/* 占满空间 */
width: 100%;
height: 100%;
/* 移除边距 */
margin: 0;
/* 允许纵向滚动 */
overflow-y: hidden;
}
.body {
/* body在底部 */
z-index: 1;
}
.wrapper {
/* 容器在上部 */
z-index: 2;
}
Canvas 性能实践
使用requestAnimationFrame
setInterval
requestAnimationFrame
1000/60 ≈ 16.67ms
使用cancelAnimationFrame
Canvas 分层
对于静态或更新频率较低的画面可以放到另外一层画布上,画布间使用z-index
使用 “离屏绘制”
Canvasdocument.createElement()
与ctx.drawImage()
方法,维护一个小尺寸的画布作为原始数据,画板会更容易实现缩放、平移等功能
Canvas 禁用自动平滑(使用临近缩放)
对于像素画风的应用或游戏很有用,绘制前设置ctx.imageSmoothingEnabled = false
,由于此属性仍为实验性质,使用时要加上前缀
ctx.mozImageSmoothingEnabled = false;
ctx.webkitImageSmoothingEnabled = false;
ctx.msImageSmoothingEnabled = false;
ctx.imageSmoothingEnabled = false;
随机数版本 uuid 生成 JS 实现
let uuid = () => {
let d = Date.now()
if (typeof performance !== 'undefined' && typeof performance.now === 'function') {
d += performance.now()
}
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
let r = (d + Math.random() * 16) % 16 | 0
d = Math.floor(d / 16)
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16)
})
}
生成随机十六进制色值
getRandomColor() {
let result = [];
for (let i = 0; i < 16; i++) {
result.push("#" + ((Math.random() * 0xffffff) << 0).toString(16));
}
return result;
}
node.js 相关
图片裁剪、缩放
const sharp = require('sharp')
sharp('path/to/image.png')
.extract({
left: 0,
top: 100,
width: 1080,
height: 1080
})
.resize(128, 128, {
kernel: 'nearest' // 临近算法
})
.toBuffer((_err, data, info) => {
console.log(info, data)
})
简单命令行参数获取
const argv = require('optimist').argv
console.log(argv)
获取图片像素信息
const getPixels = require('get-pixels')
getPixels('path/to/image.png', function (_err, pixels) {
let pixels = []
for (let y = 0; y < pixels.shape[1]; y++) {
for (let x = 0; x < pixels.shape[0]; x++) {
const r = pixels.get(x, y, 0).toString(16)
const g = pixels.get(x, y, 1).toString(16)
const b = pixels.get(x, y, 2).toString(16)
const hex = `#${r}${g}${b}`
pixels.push(hex)
}
}
})
Vue-Cli 3.x 使用moment.js
、lodash
打包精简
安装webpack-bundle-analyzer
lodash-webpack-plugin
,配置vue.config.js
let webpack = require('webpack')
let BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
let LodashModuleReplacementPlugin = require('lodash-webpack-plugin')
module.exports = {
chainWebpack: config => {
config.plugin('ignore')
.use(new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/))
config.plugin('analyzer')
.use(new BundleAnalyzerPlugin())
config.plugin('loadshReplace')
.use(new LodashModuleReplacementPlugin())
}
}
Vue-Router 按需加载页面,JS 分包
组件定义为
使用魔术注释/* webpackChunkName: "chunkName" */
import Vue from 'vue'
import Router from 'vue-router'
const Artwork = (resolve) => {
import(/* webpackChunkName: "artwork" */ './views/artwork.vue').then((module) => {
resolve(module)
})
}
Vue.use(Router)
export default new Router({
routes: [
{
path: '/artwork',
name: 'artwork',
component: Artwork
}
]
})