现在很多for Mobile的H5网页内都有快速滚动和回弹的效果,看上去和原生app的效率都有得一拼。

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

-webkit-overflow-scrolling : touch;

可用以下网页测试:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta charset="utf-8" />
<title>scroll</title>
<style type="text/css">
.container {
width : 300px;
height : 50%;
-webkit-box-sizing : border-box;
position : relative;
overflow-y : auto;
background-color : cyan;
-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>

可以用手指滑动中间的蓝色区域,会发现回弹效果以及滚动得很快:


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

实际上,Safari真的用了原生控件来实现,对于有-webkit-overflow-scrolling的网页,会创建一个UIScrollView,提供子layer给渲染模块使用。创建时的堆栈如下:

Thread 1, Queue : 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 ()
#11 0x01d09af5 in __CFRunLoopRun ()
#12 0x01d08f44 in CFRunLoopRunSpecific ()
#13 0x01d08e1b in CFRunLoopRunInMode ()
#14 0x01cbd7e3 in GSEventRunModal ()
#15 0x01cbd668 in GSEventRun ()
#16 0x00032ffc in UIApplicationMain ()
#17 0x00002ae2 in main at /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 beingRemoved; // @synthesize beingRemoved=_beingRemoved;
@property(retain, nonatomic) DOMNode *node; // @synthesize node=_node;
@property(retain, nonatomic) UIWebOverflowContentView *overflowContentView; // @synthesize overflowContentView=_overflowContentView;
@property(retain, nonatomic) UIWebOverflowScrollListener *scrollListener; // @synthesize scrollListener=_scrollListener;
@property(nonatomic) UIWebDocumentView *webDocumentView; // @synthesize webDocumentView=_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; @end

其还有一个子View作为ContentView,是给WebCore真正用作渲染overflow型内容的layer的容器。

UIWebOverflowContentView的声明为:

@interface UIWebOverflowContentView : UIView
{
} - (void)_setCachedSubviews:(id)arg1;
- (void)_replaceLayer:(id)arg1;
- (void)fixUpViewAfterInsertion;
- (id)superview;
- (id)initWithLayer:(id)arg1; @end

再往底层跟,都是CALayer的操作。

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

ACCELERATED_COMPOSITING

这个宏里。

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

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

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

网页在Safari快速滚动和回弹的原理: -webkit-overflow-scrolling : touch;的实现的更多相关文章

  1. Mobile-H5网页快速滚动和回弹

    现在很多for Mobile的HTML5网页内都有快速滚动和回弹的效果,看上去和原生app的效率都有得一拼. 要实现这个效果很简单,只需要加一行css代码即可: -webkit-overflow-sc ...

  2. ios客户端快速滚动和回弹效果的实现

    现在很多for Mobile的HTML5网页内都有快速滚动和回弹的效果,看上去和原生app的效率都有得一拼. 要实现这个效果很简单,只需要给容器加一行css代码即可 -webkit-overflow- ...

  3. Mobile的HTML5网页内快速滚动和回弹的效果

    style="overflow: auto;-webkit-overflow-scrolling: touch; 这个可以让页面在Native端滚动时模拟原生的弹性滚动效果 下面是微信浏览器 ...

  4. -webkit-overflow-scrolling : touch 快速滚动 回弹 效果

    现在很多for Mobile的HTML5网页内都有快速滚动和回弹的效果,看上去和原生app的效率都有得一拼. 要实现这个效果很简单,只需要在元素上加一行css代码即可: -webkit-overflo ...

  5. 源生js惯性滚动与回弹效果

    在写移动端的APP或者页面时,经常会遇到惯性滚动与回弹效果.用插件iscroll可以轻松解决这个问题,大多数的移动框架也能轻松解决这个问题,它们内部都封装了这个效果. 一直好奇这个效果原生JS是怎么实 ...

  6. ScrollMe – 在网页中加入各种滚动动画效果

    ScrollMe 是一款 jQuery 插件,用于给网页添加简单的滚动效果.当你向下滚动页面的时候,ScrollMe 可以缩放,旋转和平移页面上的元素.它易于设置,不需要任何自定义的 JavaScri ...

  7. 网页HTML代码:滚动文字的制作

    本节笔者讲述HTML代码中比较特殊的标签,它能使网页中的文字滚动,并且可以控制其滚动的属性. 制作滚动文字 通过本章前面的学习,读者已经能够很好地控制各种段落文字的显示方式,不过无论怎么设置,文字都是 ...

  8. Android系统联系人全特效实现(下),字母表快速滚动

    在上一篇文章中,我和大家一起实现了类似于Android系统联系人的分组导航和挤压动画功能,不过既然文章名叫做<Android系统联系人全特效实现>,那么没有快速滚动功能显然是称不上&quo ...

  9. RecyclerView 实现快速滚动

    RecyclerView 实现快速滚动 https://www.cnblogs.com/mamamia/p/8311449.html

随机推荐

  1. Android API在不同版本系统上的兼容性

    随着安卓版本的不断更新,新的API不断涌出,有时候高版本的API会在低版本crash的. 如果minSdkVersion设置过低,在build的时候,就会报错(Call requires API le ...

  2. php正则的使用[替换,匹配]

    // 隐藏电话的中间四位 echo parseMobile('15836365252'); function parseMobile($mobile, $start = 4, $len = 4){ $ ...

  3. Httpwatch 工具介绍

    一 概述: HttpWatch强大的网页数据分析工具.集成在Internet Explorer工具栏.包括网页摘要.Cookies管理.缓存管理.消息头发送/接受.字符查询.POST 数据和目录管理功 ...

  4. 如何查询Oracle性能监控

    1.监控等待事件select event,sum(decode(wait_time,0,0,1)) prev, sum(decode(wait_time,0,1,0)) curr,count(*)fr ...

  5. Delphi 的接口机制——接口操作的编译器实现过程(1)

    学习COM编程技术也快有半个月了,这期间看了很多资料和别人的程序源码,也尝试了用delphi.C++.C#编写COM程序,个人感觉Delphi是最好上手的.C++的模版生成的代码太过复杂繁琐,大量使用 ...

  6. setPluginsEnabled(true) 谁知道android的4.3之后为什么会报错

    我也是最近才遇到这个问题的,查了下资料,setPluginEnable已经弃用了,使用webSettings.setPluginState(WebSettings.PluginState.ON);可以 ...

  7. [Leetcode][Python]27: Remove Element

    # -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 27: Remove Elementhttps://oj.leetcode.c ...

  8. Servlet的运行方式

    通常我们运行servlet需要在web.xml配置文件中,注册我们写好的servlet以及其对应的访问路径. 在学习web开发中,有一种不需要配置便可以直接对servlet进行配置的方式,在web.x ...

  9. python entry points 例子

    pbr的介绍不多,http://ju.outofmemory.cn/entry/156745 $ mkdir entry_test; cd entry_test; git init $ mkdir  ...

  10. EOF 空格问题

    mysql -u $USER -p${PASSWORD} $DATABASE << EOF >/tmp/dd-$$ 2>/tmp/ddd-$$select *from $TAB ...