网页自动滚屏实现技巧

2011-06-26 by Dron

网页上,为了方便用户及时看到有价值的信息,通常会采用自动滚屏的交互效果,使变化的信息在第一时间呈现。

滚屏的实现,普遍做法是改变网页根节点的 scrollTopscrollLeft 属性,就像这样:

document.documentElement.scrollTop = 500; // 滚动到 500px 的位置

scrollTopscrollLeft 属性接受一个数值,需要涉及到元素位置的计算(记得那个复杂的位置计算的算法么?),对于需要滚动至某个元素可见,scrollTop 和 scrollLeft 不见得是最优的方案,其实,除了这种办法,我们还可以有以下两种办法来达到滚动的目的。

利用锚点

地址栏中 # 号后面的字符串叫做 hash,浏览器在网页打开完成后或者在 hash 值改变时,会自动滚屏至名称与 hash 值相等的锚点元素位置上,利用这个特性,我们可以在需要的位置插入锚名,然后通过改变 location.hash 的值来达到滚屏效果,具体写法这里就不细说了。

这种方案有一定缺陷,在某些浏览器下,hash 值的改变会产生浏览历史记录,导致对历史记录的破坏,影响用户使用前进后退功能;而且,在一些网页里,hash 值可能会有其它的用途,这样做将影响到这些功能。

利用有焦点特征的元素的 focus() 方法

很多元素都具有焦点(比如链接和所有表单元素等等),这些元素通常会有一个方法 focus(),它的效果是将网页当前焦点移向它(也叫聚焦),如果该元素不在用户可见范围内,浏览器会自动滚屏至该元素可见。如果我们希望网页滚屏至某个元素上,可以利用浏览器的这个特性,在需要的位置安插一个用户“看不到”的按钮,并将焦点移向它。注意,我们安插的这个元素,不能使之隐藏(比如 display:none),否则在 focus 的时候,浏览器会报错,虽然不能隐藏,我们可以 width 和 height 都为 0 嘛。

最近在写一个系统,刚好用到了滚屏这种交互,也是采用了这种做法,我写了个简单 Demo,请点击这里,太久没有裸写 JS 了,大家凑合着看吧。

这种方案也有缺陷,因为一个窗口只有一个焦点,如果焦点被我们移走了,可能会影响用户的操作体验,特别是对于喜欢用 tab 键的用户。

说了三种方法,都有一些问题,那么有没有完美的方案呢?个人认为,根据实际情况,选择合适的方案才最为稳妥,一点小经验,仅供参考。