我们在移动端的页面中有时候会使用到IScroll
的滚动组件,要么是应用到页面的整个区域,要么是其中的某个div。当我们已经对这块区域进行初始化后,再向页面中添加元素时会出现什么情况呢?
1. 向滚动区域中添加元素 #
一种情况是向滚动区域中添加元素,这个元素影响到了滚动内容的高度,比如这样的代码,.main
是滚动区域的外壳:
var myscroll = new IScroll('.main', {
mouseWheel: true,
scrollbars: true
});
document.querySelector('.main .con').innerHTML += '<div>author: wenzi</div>';
在向页面中添加一个div元素后,如果不做任何改动,滚动条拉到底部是看不到这个新div元素的。只有使用refresh()
方法,刷新滚动区域后,滚动条才重新计算:
myscroll.refresh();
2. 向滚动区域的父级元素中添加元素 #
还有一种情况就是向滚动区域的父级元素中添加元素,比如直接追加到元素body中:
document.querySelector('.main .con').innerHTML += '<div>author: wenzi</div>';
当我们以innerHTML
方式向body中追加元素后,出现了一个严重的问题,IScroll滚动区域直接卡死,无法滚动了。即使使用refresh()
方法也不能奏效。
那么是什么原因造成的呢?问题就出在innerHTML
上,使用innerHTML为该元素添加html代码时,实际上是重写了该元素里所有的html代码,之前的代码全部被覆盖掉,才导致绑定在内部的IScroll事件失效,无法进行滚动了。
在第一部分中,因为修改的是在IScroll滚动区域内部的内容,不会影响到IScroll的执行,所以添加的内容只是影响了滚动区域的高度,但滚动功能还是能正常使用的。
我们可以再做一个实验: 使用innerHTML
向.main
元素的兄弟元素里添加或者修改元素,IScroll是完全没有影响的。
3. 解决方案 #
那使用什么方法向某个元素(比如body)中追加元素呢,答案是appendChild
了,我们可以先用createElement创建一个div元素,然后把内部所有的内容都填充到这个div的内容,然后再在该元素上appendChild这个div元素:
var div = document.createElement('div');
div.className = 'dialog';
div.innerHTML = '<div class="con">author: wenzi</div>';
document.querySelector('body').appendChild(div);
这种方式既不会对IScroll造成影响,也不用对IScroll的代码进行改动。方便作为第三方向某个成熟的系统中添加代码,不会对原系统产生影响。
4. 总结 #
关于innerHTML和appendChild,这里稍微总结下:
- | innerHTML | appendChild |
---|---|---|
功能 | 重写该元素内所有的html | 向该元素追加一个子元素 |
性能 | 高 | 低 |
事件 | 需添加到页面上才能绑定事件 | 创建后即可绑定事件 |
耦合度 | 高 | 低 |
关于使用哪种方式添加元素还得看这个项目的复杂程度。如果仅仅要实现一个简单的需求的话,用innerHTML性能还是好些。如果需要大规模重写html的话,可以使用模板引擎来完成。