项目心得总结

1. 慎用element.innerHTML:

因为有的时候原先dom里面的一些元素注册了一些事件,当你直接innerHTML的时候,会直接替换掉那些已经注册了事件的dom元素,会导致你的一些js效果出现问题,而且在页面的性能上也有造成不小的消耗,所以说需要更新页面的数据的时候,需要最小程度的更新dom,例如有个场景是渲染一张图片,而这个图片会随着某些情况进行渲染不同的图片,代码如下:

1
<div class="container"></div>  //图片的容器

刚开始的时候 我们可以用innerHTML的模式插入一个dom

1
2

document.querySelector('.container').innerHTML = '<img src= "..." />'

当第二次要重新改的时候,我们就要判断里面是否有元素了,所以代码应该这样:

1
2
3
4
5
const container = document.querySelector('.container')
if (container.querySelector('img')){
container.querySelector('img').src = '...'
}
//这样就避免了页面重排,也避免了如果之前的img 注册了一些事件,那该事件就会被移除

这里只是提供一些思想,代码只是举例,不可照搬

2. 注册事件

  1. 注册事件的时候最好不要在有可能经常执行的方法上注册,例如react中的render方法中,因为render方法会随时执行,这时候没执行一次,就会去注册一次,显然是不妥的
  2. 在dom中注册事件的时候最好使用事件委托,好处就是提高页面的性能,也不容易出现dom更新的时候出现,原先注册事件的dom不在了,从而引起一系列的问题,而且新来的dom也一样会有事件响应
    1
    2
    3
    4
    5
    6
    <ul id="ul1">
    <li>111</li>
    <li>222</li>
    <li>333</li>
    <li>444</li>
    </ul>

通常在li上注册事件

1
2
3
4
5
6
7
var oUl = document.getElementById("ul1");
var aLi = oUl.getElementsByTagName('li');
for(var i=0;i<aLi.length;i++){
aLi[i].onclick = function(){
alert(123);
}
}

使用事件委托

1
2
3
4
5
6
7
8
9
var oUl = document.getElementById("ul1");
  oUl.onclick = function(ev){
    var ev = ev || window.event;
    var target = ev.target || ev.srcElement;
    if(target.nodeName.toLowerCase() == 'li'){
         alert(123);
        alert(target.innerHTML);
    }
  }

如果li数量很多的话,将大大减少dom的操作,优化的性能可想而知!

3. 资源选择性的require方式

在业务场景中会遇到一种情况就是,比如一个logo 有中文,英文2中形式,这个时候有些人是这样处理的

1
2
3
4
5
6
7
const language = system.getLanguage()
let logo
if (language === 'zh-CN') {
logo = require('中文地址')
} else {
logo = require('英文地址')
}

这样处理有个问题是如果系统新增了一个语言的话,比如阿拉伯语,这里可能就要增加一个else if (),显然这种方式代码看上去比较繁重,而且后续的维护也不太方便,我们推荐使用下面这种方法,代码如下:

1
2
const language = system.getLanguage()
const logo = require(path + language + '.jpg|.png')

这时候只需要把图片配成zh—CN.jpg,或者en-US.jpg的模式就可以了,随便你加多少个语言,我们加个图片就可以了,简单2句话搞定,不需要太多的代码,简单优雅,而且维护起来方便,改图片名称,总比改代码代价小的多的多

4. 缓存机制提高用户体验

当有些数据不会时时更新的情况下,可以进行缓存处理,就是在去数据之前,先去渲染缓存,然后去取数据,取好的数据跟缓存的数据对比,只有有变化的时候再去重新更新dom的数据,这样用户就不会在看到数据之前 页面可能会有段空白期,体验上感觉会舒适一些

5. 取dom一些属性的问题

看下面代码:

1
2
3
4
5
6
7
function appendDom() {
const div = document.createElement('div')
div.className = 'testDom'
const height = div.offsetHeight
document.body.appendChild(div)
}
appendDom();

在上面代码中 height的值会是null,因为这个时候,dom并没有插入到页面的body中去,所以这个时候offsetHeight这个时候是null的,所以取height需要确保dom已经插入到页面中的时候才去取,代码可以修改成:

1
2
3
4
5
6
7
8
9
10
let height, div
function appendDom(cb) {
div = document.createElement('div')
div.className = 'testDom'
document.body.appendChild(div)
cb && cb()
}
appendDom(function() {
height = div.offsetHeight
});

这时候就可以取到offsetHeight了