你不得不知道的开发技巧-JS篇


文章同步于 我的 Segmentfault 笔记

1. 使用 mock.js 时, post 请求参数 cache 不能为 false , 否则不能正常拦截, (一般是)导致 status: 404 错误

2. 关于 export 与 import 的用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 1. 输出单个匿名函数或值
export default function(){...} // A.js
export default 100 // $.js 或使用 var、const声明变量

// 使用
import fn from 'A.js' // B.js 一般这种情况,是需要使用 fn 时再执行它 fn()
import 'A.js' // C.js 不给被引用的模块指定变量名, 这种情况一般 A.js 是一个立即执行函数

// 2. 输出多个
// A.js 多个非匿名函数、变量
export a1 = function(){...}
export a2 = function(){...}
export const NAME = 'superman';

// A.js 多个变量
let a1 = 0;
let a2 = 1;
export {a1, a2} // 错误语法:直接export a1 = 0; export a2 = 1;

// 使用
import {a1, a2} form 'A.js' //全引入
import {a2, NAME} from 'A.js' //只引入其中一个

3. 当我们需要一个全屏的遮罩层内部可以实现滚动条滚动, 但是在阴影区域滚动又不能导致底下正常文档的滚动,可以解决的方法有:

  • 遮罩的阴影区和遮罩的内容区,在 html 结构上是非父子级关系,在阴影区阻止默认行为
  • 弹出遮罩的时候给 body 添加 overflow: hidden, 并记录此时 bodyscrollTop 值,当退出遮罩的时候,去掉 bodyoverflow:hidden 并还原 scrollTop

4. 使用 intypeof 操作符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
'onclick' in window                 // true
typeof onclick // 'object'

'onwebkitanimationend' in window // true
typeof onwebkitanimationend // 'object'

'ontransitionend' in window // true
typeof ontransitionend // 'object'

'onpopstate' in window // true
typeof onpopstate // 'object'

// 如果是判断支持那种前缀(-o-, -webkit-, -ms-):
var style = document.createElement('div').style;

'transition' in style // true
typeof style.transition // 'string'

'-webkit-animation' in style // true
typeof style.WebkitAnimation // 'string'

'-webkit-animation' in style // true
typeof style['-webkit-animation'] // 'string'

5. 使用 zepto.js 时以外发现,有些时候使用 $el.trigger(eventName) 可以触发,有些时候确要使用 $el.triggerHandler(eventName) 才能触发?

– 暂时不知原因 –

6. 使用 transition 属性实现下拉动效时,通常会在 css 部分设置元素 { height: 0 }, 会在 js 部分添加

1
2
3
4
5
6
7
8
9
$el.css({'position': 'absolute', 'height': 'auto', 'opacity': '0'});
var elHeight = $el.height();
$el.prop('style', '').height( elHeight );

// 这样的写法本没什么问题,但是一些浏览器的表现并不一致。
// 会导致某些机型下,$el 的 opacity 仍为0,
// 宽度因为 position:absolute 而变成自适应,并不是我们期望的结果。

// 解决办法:只设置 $el.css({'height':'auto''})

7. swiper.js的基本使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var swiperCommonOption = {
direction: 'vertical',
height: 150 / 375 * docFontsize * 10,
centeredSlides: true, // 滑动块居中
slidesPerView: 5, // 可见的 item 数量
initialSlide: 15,
freeMode: true,
freeModeSticky: true, // 结束后边贴合
freeModeMomentumRatio: 0.32, // 默认1, 设置的值越大,当释放slide时的滑动距离越大。
freeModeMomentumVelocityRatio: 1, // 默认1, 设置越大,释放后滑得越快
onInit: function(){},
onTouchMove: function(){},
onTransitionEnd:function(){}
};

8. 函数体内定义一个函数时,例如回调函数如 onload 、事件函数 onclick 等,需考虑闭包的影响,手动回收内存防止内存泄露(特别是图片上传 FileReader 的 onload 事件):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function handle(){
var oA = document.getElementById('a');
oA.onclick=function(){
oA.onclick = null;
// ...
}
}
// 或者直接把click事件函数定义在外部

const files = ev.target.files;
for(let i=0;i<files.length;i++){// 采用 let 形成的闭包
const reader = new FileReader();
reader.readAsDataURL(files[ i ]);
reader.onload = function(){
//...
reader = null
}
}

9. 逻辑与 &&、逻辑或 ||、三元表达式 ?: 的执行顺序的优先级

1
2
3
4
5
// && 优于 || 优于 ?:
true && false || true // true
false && false || true && true // true
true && false ? '1': '2' // '2'
true || false ? '1':'2' // '1'

10. 尽可能使用 transform: translate3d()scale() 代替位移和大小变化

11. 如何共享 window.sessionStorage 缓存数据?(大前提肯定必须是同域)

  • <a hrf="/">旧标签页面</a>
  • <a hrf="/" target="_blank">新标签页面</a>
  • 使用 window.open() 打开新标签

12. 如需将 ajax 的返回值赋值给一个变量 a, 那么不应该直接在 success 回调中直接 return data, 而应该取内部变量value赋值再 return value, 否则得到的 a === undefined

1
2
3
4
5
6
7
8
9
10
11
12
var a = (function(){
var value;
$.ajax({
async: true,
// ...
success: function(data){
//return data 错误.无效
value = data
}
});
return value;
}());

13. 使用选择器 better-picker 时,部分 android 机可能出现闪现(而不是过渡动画显现)的问题, 这是由于源码对 show() 方法采用的是 setTimeout(()=>{...},0) 的操作,只需要改延迟时间为10即可

14. 在 <iframe> 中引入百度地图时, 有时候会出现强制跳转到非指定链接.需要在 <iframe> 标签中添加属性 security="restricted" sandbox="" 来阻止

1
2
3
4
5
6
<iframe src="https://api.map.baidu.com/marker?location=26.0680890068,119.3112705072"
frameborder="0"
security="restricted"
sandbox=""
>
</iframe>

15. 数组或者对象的排序之sort方法:

1
2
3
4
5
6
7
8
9
10
11
var arr = [1, 3, 0.5, 33, 21, 78, 0, "87"];
//从小到大:
arr.sort((a, b) => a - b); // [0, 0.5, 1, 3, 21, 33, 78, "87"]
// 从大到小:
arr.sort((a, b) => b - a); // ["87", 78, 33, 21, 3, 1, 0.5, 0]

var obj=[{a: 3}, {a: 6}, {a: '17'}, {a: 30}, {a: 2}, {a: 0.3}];
// 从小到大:
obj.sort((o1, o2) => o1.a - o2.a); // [{a: 0.3}, {a: 2}, {a: 3}, {a: 6}, {a: "17"}, {a: 30}]
//从大到小:
obj.sort((o1, o2) => o2.a - o1.a); // [{a: 30}, {a: "17"}, {a: 6}, {a: 3}, {a: 2}, {a: 0.3}]

16. 使用npm开发时,如若出现 can not find XX module 信息提示, 但是这些模块并不是依赖模块时,这时应该考虑使用

1
$ rimraf node_modules

删除, 然后再重新安装

1
$ npm install

17. 当遇到有 tab 按钮切换页面时,我们经常需要一个 tab 对应一个页面,且首次点击 tab 键时会首次获取页面的初始化数据,且再次点击时不会再请求。那么我们可以先把点击事件和放重复触发写完,然后再使用jquery的trigger函数,来触发首次进入整个页面时,要显示的页面。

18. 在webkit内核的浏览器下, 对<input type="number">(或type=”text”等)使用 oninput 事件可能出现报错(这是webkit浏览器的错误):

1
2
3
"Failed to execute 'setSelectionRange' on 'HTMLInputElement': The input element's type ('number') does not support selection."
// 解决办法: $(input).on('input keyup')
// 其他参考答案: https://stackoverflow.com/questions/23012370/failed-to-execute-setselectionrange-on-htmlinputelement

19. removeEventListener 的注意事项

  • 移除的事件所对应的函数必须是同一个(同一个地址), 即不能是匿名函数
  • 不能再事件函数绑定this, 即 fn.bind(obj)

20. 当我们使用 webpack 去引用静态资源如图片时, 有时候难免需要使用到变量去代替, 即 require(imgUrl), 但是直接引用的话, webpack会报错.解决办法是: imgUrl需要使用3个部分组成

1
2
3
4
5
6
7
8
9
require('../../' + imgPath + '.png');
/*
'../../' => 告诉webpack去哪里读取资源(显示声明)
imgPath => 文件的路径+名称
'.png' => 文件的后缀名(显示声明)
*/

// 或
require('../images/' + imgPath);

* 有意思的比较

1
2
3
4
null === null  // true
Object === Object // true
Array === Array // true
document === document // true
最近的文章

你不得不知道的开发技巧-CSS篇

文章同步于 我的 Segmentfault 笔记1. 关于移动端 css 样式:123456789101112// 不允许浏览器擅自改变字体大小:【font boosting】html&#123; -webkit-text-size-adjust: 100%;&#125;// 否则当你设置了,如 …

继续阅读
更早的文章

关于VUE的一些使用技巧

前言Vue.js 是一套渐进式的 JavaScript MVVM框架,2014 年 2 月,其作者尤雨溪(Evan You)第一次将它作为实际的项目发布在 Github 上,在短短一周内就收获了几百个star,2016 年 9 月,Vue 2.0正式发布。截止目前为止( 2018 年 05 月 1 …

分享记录 继续阅读