网页在Safari快速滚动和回弹的原理:-webkit-overflow-scrolling:touch;的实现

来源:互联网 发布:单片机c51简易数字钟 编辑:程序博客网 时间:2024/05/21 20:24

现在很多的移动的HTML5网页内都有快速滚动和回弹的效果,看上去和原生应用的效率都有得一拼。

要实现这个效果很简单,只需要加一行CSS代码即可:

[css] 查看纯文本 
  1. -webkit-overflow-scrolling:touch;  
可用以下网页测试:

[html] 查看纯文本 
  1. <!DOCTYPE html PUBLIC“ - // W3C // DTD HTML 4.01 Transitional // EN” >  
  2. html >  
  3.     head >  
  4.         meta charset “utf-8” />    
  5.         title 滚动</ title >  
  6.         style type “text / css” >   
  7.             。容器 {  
  8.                 宽度:300px;  
  9.                 身高:50%;  
  10.                 -webkit-box-sizing:border-box;  
  11.                 位置:亲戚;  
  12.                 overflow-y:auto;  
  13.                 背景颜色:青色;  
  14.                 -webkit-overflow-scrolling:touch; / * liuhx:可以把这整行注释掉对比差别* /  
  15.             }  
  16.             ul {  
  17.                 height:50px;  
  18.             }  
  19.         </ style >  
  20.     </ head >  
  21. body >  
  22.     div align “center” >   
  23.         nav class “container” >   
  24.             ul </ ul >  
  25.             ul </ ul >  
  26.             ul </ ul >  
  27.             ul </ ul >  
  28.             ul </ ul >  
  29.             ul </ ul >  
  30.             ul </ ul >  
  31.             ul </ ul >  
  32.             ul </ ul >  
  33.             ul 10 </ ul >  
  34.             ul 11 </ ul >  
  35.             ul 12 </ ul >  
  36.             ul 13 </ ul >  
  37.             ul 14 </ ul >  
  38.             ul 15 </ ul >  
  39.             ul 16 </ ul >  
  40.             ul 17 </ ul >  
  41.             ul 18 </ ul >  
  42.             ul 19 </ ul >  
  43.             ul 20 </ ul >  
  44.         </ nav >  
  45.     </ div >  
  46. </ body >  
  47. </ html >  
可以用手指滑动中间的蓝色区域,会发现回弹效果以及滚动得很快:


(点击图片查看大图)
如果把-webkit溢出滚动那行注释掉,就会发现滚动得很慢。


实际上,Safari浏览器真的用了原生控件来实现,对于有-webkit溢出滚动的网页,会创建一个的UIScrollView,提供子层给渲染模块使用创建时的堆栈如下:

[平原] 视图平原拷贝 
  1. 线程1,队列:com.apple.main-thread  
  2. #0 0x00086723 in - [UIScrollView initWithFrame:]()  
  3. #1 0x004ec3bd in - [UIWebOverflowScrollView initWithLayer:node:webDocumentView:]()  
  4. #2 0x001f1769 in - [UIWebDocumentView webView:didCreateOrUpdateScrollingLayer:withContentsLayer:scrollSize:forNode:allowHorizo​​ntalScrollbar:allowVerticalScrollbar:]()  
  5. #3 0x01d571bd in __invoking___()  
  6. #4 0x01d570d6 in - [NSInvocation invoke]()  
  7. #5 0x01d5724a in - [NSInvocation invokeWithTarget:]()  
  8. #6 0x027fb6a1 in - [_ WebSafeForwarder forwardInvocation:]()  
  9. #7 0x027fb8ab in __44 - [_ WebSafeAsyncForwarder forwardInvocation:] _ block_invoke_0()  
  10. #8 0x04ac753f in _dispatch_call_block_and_release()  
  11. #9 0x04ad9014 in _dispatch_client_callout()  
  12. #10 0x04ac97d5 in _dispatch_main_queue_callback_4CF()  
  13. _CFRunLoopRun()中的#11 0x01d09af5  
  14. CFRunLoopRunSpecific()中的#12 0x01d08f44  
  15. CFRunLoopRunInMode()中的#13 0x01d08e1b  
  16. GSEventRunModal()中的#14 0x01cbd7e3  
  17. #15 0x01cbd668在GSEventRun()  
  18. UIApplicationMain()中的#16 0x00032ffc  
  19. #17 0x00002ae2主要在/Users/liuhx/Desktop/UIWebView_Research/WebViewResearch/main.mm:16  
实际创建的是UIWebOverflowScrollView,它继承自UIScrollView的,声明为:

[cpp] 查看纯文本 
  1. class  DOMNode,UIWebDocumentView,UIWebOverflowContentView,UIWebOverflowScrollListener;  
  2.   
  3. @interface UIWebOverflowScrollView:UIScrollView  
  4. {  
  5.     UIWebDocumentView * _webDocumentView;  
  6.     UIWebOverflowScrollListener * _scrollListener;  
  7.     UIWebOverflowContentView * _overflowContentView;  
  8.     DOMNode * _node;  
  9.     BOOL  _beingRemoved;  
  10. }  
  11.   
  12. @property(nonatomic,getter = isBeingRemoved)  BOOL  beRemoved; // @synthesize beingRemoved = _beingRemoved;  
  13. @property(retain,nonatomic)DOMNode * node; // @synthesize node = _node;  
  14. @property(retain,nonatomic)UIWebOverflowContentView * overflowContentView; // @synthesize overflowContentView = _overflowContentView;  
  15. @property(retain,nonatomic)UIWebOverflowScrollListener * scrollListener; // @synthesize scrollListener = _scrollListener;  
  16. @property(nonatomic)UIWebDocumentView * webDocumentView; // @synthesize webDocumentView = _webDocumentView;  
  17. - (void )setContentOffset :( struct  CGPoint)arg1;  
  18. - (void )_replaceLayer:(id)arg1;  
  19. - (void )prepareForRemoval;  
  20. - (void )fixUpViewAfterInsertion;  
  21. - (id)superview;  
  22. - (void )dealloc;  
  23. - (id)initWithLayer:(id)arg1 node:(id)arg2 webDocumentView:(id)arg3;  
  24.   
  25. @结束  
其还有一个子查看作为内容查看,是给WebCore的真正用作渲染型内容溢出的层的容器。

UIWebOverflowContentView的声明为:

[cpp] 查看纯文本 
  1. @interface UIWebOverflowContentView:UIView  
  2. {  
  3. }  
  4.   
  5. - (void )_setCachedSubviews:(id)arg1;  
  6. - (void )_replaceLayer:(id)arg1;  
  7. - (void )fixUpViewAfterInsertion;  
  8. - (id)superview;  
  9. - (id)initWithLayer:(id)arg1;  
  10.   
  11. @结束  
再往底层跟,都是CALayer的的操作。


以上两个类都是UIKit的层的实现,需要的WebCore有硬件加速的支持才有实际意义,相关的逻辑被包含在

ACCELERATED_COMPOSITING

这个宏里。

从SVN日志看,在WebKit 108400版本左右才支持,所以iOS Safari应该是需要5.0.Android只在4.0以上支持。


从前端开发的角度讲,只需要知道CSS的属性-webkit-溢出滚动是真的创建了带有硬件加速的系统级控件,所以效率很高。但是这相对是耗更多内存的,最好在产生了非常大面积的溢出时才应用。


转载请注明出处:http //blog.csdn.net/hursing

阅读全文
0 0
原创粉丝点击