JavaScript 书写规范及技巧

强类型检查

使用 === 而不是 ==

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
0 == false // true 
0 === false // false
2 == "2" // true
2 === "2" // false

// example
const val = "123";
if (val === 123) {
console.log(val);
// it cannot not be reached
}
if (val === "123") {
console.log(val);
// it can be reached
}

变量命名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 不推荐
let daysSLV = 10;
let y = new Date().getFullYear();
let ok;
if (user.age > 30) {
ok = true;
}

// 推荐
const MAX_AGE = 30;
let daysSinceLastVisit = 10;
let currentYear = new Date().getFullYear();
...
const isUserOlderThanAllowed = user.age > MAX_AGE;

// 不要添加一些额外且不必要的词汇到你的变量名称中。

let nameValue;
let theProduct;

// 推荐
let name;
let product;

设置原型的构造函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function Person(name) {
this.name = name;
}


function Student(name) {
Person.call(this, name);
}

Student.prototype = Object.create(Person.prototype);
// Student 的原型会被设置为 Person。

// 实际上想要将 Student 的原型设置为 Student。
// 需要这么写
Student.prototype.constructor = Student;

// 或者
class Student extends Person {
}

创建 Web Workers

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<script id="worker" type="javascript/worker">
self.onmessage = (e) => {
self.postMessage('msg');
};
</script>
<script>
const blob = new Blob([
document.querySelector('#worker').textContent
]);

const worker = new Worker(window.URL.createObjectURL(blob));
worker.onmessage = (e) => {
console.log(e.data);
}
worker.postMessage("hello");
</script>

map 技巧

map 里使用 parseInt 会返回 NaN

1
2
3
4
5
6
//  不要这么写
['1','2','3'].map(parseInt)

// 可以
['1','2','3'].map(Number)
['1','2','3'].map(num => parseInt(num, 10))

三目运算符

1
2
3
4
5
// 当 x === 1 返回 false 不想调用 doSomethingElse 时
x === 1 ? doSomething() : doSomethingElse();

// 可以
x === 1 && doSomething();

清除 Yarn 中的缓存

1
yarn cache clear

innerText 在 IE 有效,其他浏览器无效

1
2
const el = document.getElementById('foo');
el.textContent = 'foo';

[译] JavaScript 技巧 —— 子代构造函数,文本选择,内联 Workers 等等
【译】JS代码整洁之道——快速最佳实践
JavaScript闭包应用介绍
如何精确统计页面停留时长

CSS 库

animate.css

css 动画库

normalize.css

初始化 CSS

Bootstrap

Foundation

Semantic UI

Pure

UIkit

Ant Design

Bulma

Spectre

Tailwind

Shoelace

Skeleton

Tachyons

Material Design

Element

WeUI

Materialize

iView

layui

Gentelella Admin

NES-style

VUX

Vant

Cube UI

CSS 单位

em 根据父元素的字体大小变化。

1
2
3
4
5
6
7
8
9
10
11
12
13
<style>
body{
font-size: 14px;
}
div{
font-size: 1.2em;
}
</style>
<body>
<div class="test">
Test
</div>
</body>

rem 根据根元素的字体大小变化。

1
2
3
4
5
6
7
8
<style>
body{
font-size: 14px;
}
div{
font-size: 1.2rem;
}
</style>

vw 显示窗口的宽度
vh 显示窗口的高度
vmin 和 vmax 宽度和高度的最大值或最小值有关(如果宽度为1100px高度为700px 那么 1vmin 是 7px,1vmax 是 11px 反之亦然。)

1
2
3
4
5
6
<style>
body{
width: 100vw;
height: 100vh;
}
</style>

ex和ch单位 这两个单位只也依赖于font-family,因为它们被定为基于特殊字体的法案。


相关资料
CSS的一些单位,如rem、px、em、vw、vh、vm
七个你可能不了解的CSS单位

效果实现

web页面内容滑动效果

事件

  • touchstart事件:手指触摸时候触发(支持多指触发)
  • touchmove事件:手指在滑动的时候连续地触发。在这个事件发生期间,调用
  • preventDefault()事件可以阻止滚动,当然也不能滥用否则会影响原有页面的上下滚动等。
  • touchend事件:手指从屏幕上离开的时候触发
  • touchcancel事件:当系统停止跟踪触摸的时候触发。关于这个事件的确切出发时间,文档中并没有具体说明。。。不建议使用

相关资料
手把手教你实现web页面内容滑动效果

图像处理

函数

图片压缩

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
const tool = {
//base64转file
dataURLtoFile (dataurl, filename) {
let arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new File([u8arr], filename, {type: mime})
},

// 压缩图片
compress (img) {
let originWidth = img.width, // 压缩后的宽
originHeight = img.height,
maxWidth = 600, maxHeight = 600,
quality = 0.8, // 压缩质量
canvas = document.createElement('canvas'),
drawer = canvas.getContext('2d');
// 目标尺寸
let targetWidth = originWidth,
targetHeight = originHeight
// 图片尺寸超过300x300的限制
if (originWidth > maxWidth || originHeight > maxHeight) {
if (originWidth / originHeight > maxWidth / maxHeight) {
// 更宽,按照宽度限定尺寸
targetWidth = maxWidth
targetHeight = Math.round(maxWidth * (originHeight / originWidth))
} else {
targetHeight = maxHeight
targetWidth = Math.round(maxHeight * (originWidth / originHeight))
}
}
canvas.width = targetWidth
canvas.height = targetHeight
drawer.clearRect(0, 0, canvas.width, canvas.height)
drawer.drawImage(img, 0, 0, canvas.width, canvas.height)
let base64 = canvas.toDataURL('image/jpeg', quality) // 压缩后的base64图片
let file = this.dataURLtoFile(base64, Date.parse(Date()) + '.jpg')
file = {content: base64, file: file}
console.log(file)//压缩后的file
return file
},
}
export default tool

图片压缩、方向纠正、预览、上传

实现原理

  • 用filereader读取用户上传的图片数据
  • 将img绘制到canvas上,用EXIF.js对图片方向进行纠正,再调用canvas.toDataURL对图片进行压缩,获取到压缩后的base64格式图片数据,转成二进制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
1. 可以直接把base64数据转为File对象,如下:
// dataUrl数据转为File对象,dataUrl表示图片的base64数据
dataURLtoFile (dataurl, filename) {
var arr = dataurl.split(',')
var mime = arr[0].match(/:(.*?);/)[1]
var bstr = atob(arr[1])
var n = bstr.length; var u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new File([u8arr], filename, { type: mime })
}
2. 或者你想把上文 方法返回的blob对象转为File对象,可以这样写:
/**
* Blob对象转为File对象
* @param {object} blob 二进制对象
* @param {string} fileName 文件名称
* @return {object} blob改造后的file文件对象。
* 注意:file对象就是一个特殊的blob对象
*/
function blobToFile(blob, fileName){
blob.lastModifiedDate =new Date();
blob.name = fileName;
return blob;
}

工具

  • RECOMPRESSOR
    在线图片优化工具,在文件尺寸和质量之间选择完美平衡。

  • 智图

在线高效优质图片优化,大图需要下载客户端。

  • Pica
    减小大图像的上传大小,节省上传时间。
    在图像处理上节省服务器资源。
    在浏览器中生成缩略图。

注意。如果您需要调整File/Blob的大小(通过表单的文件输入),请考虑使用 image-blob-reduce。

  • Lena.js
    用于图像处理的微型库,有 22 个图像滤镜。

  • Compressor.js
    JavaScript图像压缩器。使用浏览器的本机canvas.toBlob API进行压缩工作,这意味着它是有损压缩。通常使用此方法在上载客户端映像文件之前对其进行预压缩。

  • Fabric.js
    使用 canvas JavaScript 在网页上轻松创建简单的形状(如矩形,圆形,三角形和其他多边形)或由许多路径组成的更复杂的形状。Fabric.js将允许您使用鼠标来操纵这些对象的大小,位置和旋转。

  • blurify
    用于模糊图片

  • merge-images
    图像合并

  • cropperjs
    JavaScript 图像裁剪,旋转,缩放。

  • marvinj
    滤镜、裁剪

  • grade
    提供图像中的前2种主要颜色生成的互补渐变


相关资料
最优图像优化
智图
手把手教你如何编写一个前端图片压缩、方向纠正、预览、上传插件
图片压缩原理
图片懒加载从简单到复杂

高质量前端快照方案:来自页面的「自拍」
一个有趣的例子带你入门canvas
了解 JS 压缩图片,这一篇就够了


HTMLCanvasElement.toDataURL
CanvasRenderingContext2D.drawImage()
FileReader
在web应用程序中使用文件
FormData 对象的使用
Using XMLHttpRequest

uniapp 从入门到实战

uniapp

uniapp 基础

运行项目

第一次在微信开发者工具中运行需要先配置小程序的相关路径、小程序开发者工具中安全中服务端口开启

项目目录及文件

pages 所有的页面存放目录
static 静态资源目录,例如图片等
unpackage 就是打包目录,在这里有各个平台的打包文件
components 组件存放目录
App.vue 是我们的根组件,所有页面都是在 App.vue 下进行切换的,是页面入口文件,可以调用应用的生命周期函数。
manifest.json 文件是应用的配置文件,用于指定应用的名称、图标、权限等。
pages.json 文件用来对 uni-app 进行全局配置,决定页面文件的路径、窗口样式、原生的导航栏、底部的原生tabbar 等
main.js 是我们的项目入口文件,主要作用是初始化 vue 实例并使用需要的插件。
uni.scss 文件的用途是为了方便整体控制应用的风格。比如按钮颜色、边框风格,uni.scss 文件里预置了一批scss变量预置。

为了实现多端兼容,综合考虑编译速度、运行性能等因素,uni-app 约定了如下开发规范:

  • 页面文件遵循 Vue 单文件组件 (SFC) 规范
  • 组件标签靠近小程序规范,详见uni-app 组件规范
  • 接口能力(JS API)靠近微信小程序规范,但需将前缀 wx 替换为 uni,详见uni-app接口规范
  • 数据绑定及事件处理同 Vue.js 规范,同时补充了App及页面的生命周期
  • 为兼容多端运行,建议使用flex布局进行开发
阅读更多
You need to set client_id and slot_id to show this AD unit. Please set it in _config.yml.