innerHTML对IScroll组件的影响

我们在移动端的页面中有时候会使用到IScroll的滚动组件,要么是应用到页面的整个区域,要么是其中的某个div。当我们已经对这块区域进行初始化后,再向页面中添加元素时会出现什么情况呢?

1. 向滚动区域中添加元素

一种情况是向滚动区域中添加元素,这个元素影响到了滚动内容的高度,比如这样的代码,.main是滚动区域的外壳:

var myscroll = new IScroll('.main', {
    mouseWheel: true,
    scrollbars: true
});

document.querySelector('.main .con').innerHTML += '
author: wenzi
';

在向页面中添加一个div元素后,如果不做任何改动,滚动条拉到底部是看不到这个新div元素的。只有使用refresh()方法,刷新滚动区域后,滚动条才重新计算:

myscroll.refresh();

2. 向滚动区域的父级元素中添加元素

还有一种情况就是向滚动区域的父级元素中添加元素,比如直接追加到元素body中:

document.querySelector('.main .con').innerHTML += '
author: wenzi
';

当我们以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 = '
author: wenzi
'; document.querySelector('body').appendChild(div);

这种方式既不会对IScroll造成影响,也不用对IScroll的代码进行改动。方便作为第三方向某个成熟的系统中添加代码,不会对原系统产生影响。

4. 总结

关于innerHTML和appendChild,这里稍微总结下:

innerHTMLappendChild
功能重写该元素内所有的html向该元素追加一个子元素
性能
事件需添加到页面上才能绑定事件创建后即可绑定事件
耦合度

关于使用哪种方式添加元素还得看这个项目的复杂程度。如果仅仅要实现一个简单的需求的话,用innerHTML性能还是好些。如果需要大规模重写html的话,可以使用模板引擎来完成。

发表评论

电子邮件地址不会被公开。 必填项已用*标注