现在很多的移动的HTML5网页内都有快速滚动和回弹的效果,看上去和原生应用的效率都有得一拼。
要实现这个效果很简单,只需要加一行CSS代码即可:
- -webkit-overflow-scrolling:touch;
可用以下网页测试:
- <!DOCTYPE html PUBLIC“ - // W3C // DTD HTML 4.01 Transitional // EN” >
- < html >
- < head >
- < meta charset = “utf-8” />
- < title > 滚动</ title >
- < style type = “text / css” >
- 。容器 {
- 宽度:300px;
- 身高:50%;
- -webkit-box-sizing:border-box;
- 位置:亲戚;
- overflow-y:auto;
- 背景颜色:青色;
- -webkit-overflow-scrolling:touch; / * liuhx:可以把这整行注释掉对比差别* /
- }
- ul {
- height:50px;
- }
- </ style >
- </ head >
- < body >
- < div align = “center” >
- < nav class = “container” >
- < ul > 1 </ ul >
- < ul > 2 </ ul >
- < ul > 3 </ ul >
- < ul > 4 </ ul >
- < ul > 5 </ ul >
- < ul > 6 </ ul >
- < ul > 7 </ ul >
- < ul > 8 </ ul >
- < ul > 9 </ ul >
- < ul > 10 </ ul >
- < ul > 11 </ ul >
- < ul > 12 </ ul >
- < ul > 13 </ ul >
- < ul > 14 </ ul >
- < ul > 15 </ ul >
- < ul > 16 </ ul >
- < ul > 17 </ ul >
- < ul > 18 </ ul >
- < ul > 19 </ ul >
- < ul > 20 </ ul >
- </ nav >
- </ div >
- </ body >
- </ html >
可以用手指滑动中间的蓝色区域,会发现回弹效果以及滚动得很快:
![](https://img-blog.csdn.net/20130627114321171?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaHVyc2luZw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
(点击图片查看大图)
如果把-webkit溢出滚动那行注释掉,就会发现滚动得很慢。
实际上,Safari浏览器真的用了原生控件来实现,对于有-webkit溢出滚动的网页,会创建一个的UIScrollView,提供子层给渲染模块使用创建时的堆栈如下:
- 线程1,队列:com.apple.main-thread
- #0 0x00086723 in - [UIScrollView initWithFrame:]()
- #1 0x004ec3bd in - [UIWebOverflowScrollView initWithLayer:node:webDocumentView:]()
- #2 0x001f1769 in - [UIWebDocumentView webView:didCreateOrUpdateScrollingLayer:withContentsLayer:scrollSize:forNode:allowHorizontalScrollbar:allowVerticalScrollbar:]()
- #3 0x01d571bd in __invoking___()
- #4 0x01d570d6 in - [NSInvocation invoke]()
- #5 0x01d5724a in - [NSInvocation invokeWithTarget:]()
- #6 0x027fb6a1 in - [_ WebSafeForwarder forwardInvocation:]()
- #7 0x027fb8ab in __44 - [_ WebSafeAsyncForwarder forwardInvocation:] _ block_invoke_0()
- #8 0x04ac753f in _dispatch_call_block_and_release()
- #9 0x04ad9014 in _dispatch_client_callout()
- #10 0x04ac97d5 in _dispatch_main_queue_callback_4CF()
- _CFRunLoopRun()中的#11 0x01d09af5
- CFRunLoopRunSpecific()中的#12 0x01d08f44
- CFRunLoopRunInMode()中的#13 0x01d08e1b
- GSEventRunModal()中的#14 0x01cbd7e3
- #15 0x01cbd668在GSEventRun()
- UIApplicationMain()中的#16 0x00032ffc
- #17 0x00002ae2主要在/Users/liuhx/Desktop/UIWebView_Research/WebViewResearch/main.mm:16
实际创建的是UIWebOverflowScrollView,它继承自UIScrollView的,声明为:
- @ class DOMNode,UIWebDocumentView,UIWebOverflowContentView,UIWebOverflowScrollListener;
-
- @interface UIWebOverflowScrollView:UIScrollView
- {
- UIWebDocumentView * _webDocumentView;
- UIWebOverflowScrollListener * _scrollListener;
- UIWebOverflowContentView * _overflowContentView;
- DOMNode * _node;
- BOOL _beingRemoved;
- }
-
- @property(nonatomic,getter = isBeingRemoved) BOOL beRemoved;
- @property(retain,nonatomic)DOMNode * node;
- @property(retain,nonatomic)UIWebOverflowContentView * overflowContentView;
- @property(retain,nonatomic)UIWebOverflowScrollListener * scrollListener;
- @property(nonatomic)UIWebDocumentView * webDocumentView;
- - (void )setContentOffset :( struct CGPoint)arg1;
- - (void )_replaceLayer:(id)arg1;
- - (void )prepareForRemoval;
- - (void )fixUpViewAfterInsertion;
- - (id)superview;
- - (void )dealloc;
- - (id)initWithLayer:(id)arg1 node:(id)arg2 webDocumentView:(id)arg3;
-
- @结束
其还有一个子查看作为内容查看,是给WebCore的真正用作渲染型内容溢出的层的容器。
UIWebOverflowContentView的声明为:
- @interface UIWebOverflowContentView:UIView
- {
- }
-
- - (void )_setCachedSubviews:(id)arg1;
- - (void )_replaceLayer:(id)arg1;
- - (void )fixUpViewAfterInsertion;
- - (id)superview;
- - (id)initWithLayer:(id)arg1;
-
- @结束
再往底层跟,都是CALayer的的操作。
以上两个类都是UIKit的层的实现,需要的WebCore有硬件加速的支持才有实际意义,相关的逻辑被包含在
ACCELERATED_COMPOSITING
这个宏里。
从SVN日志看,在WebKit 108400版本左右才支持,所以iOS Safari应该是需要5.0.Android只在4.0以上支持。
从前端开发的角度讲,只需要知道CSS的属性-webkit-溢出滚动是真的创建了带有硬件加速的系统级控件,所以效率很高。但是这相对是耗更多内存的,最好在产生了非常大面积的溢出时才应用。
转载请注明出处:http : //blog.csdn.net/hursing