现在很多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. Chrome disable adobe flash player

    New tab and input : chrome://plugins/ so easy~!

  2. Python封装的访问MySQL数据库的类及DEMO

    # Filename:mysql_class.py # Author:Rain.Zen; Date: 2014-04-15 import MySQLdb class MyDb: '''初始化[类似于构 ...

  3. Microsoft.AlphaImageLoader滤镜讲--透明处理<转>

    Microsoft.AlphaImageLoader是IE滤镜的一种,其主要作用就是对图片进行透明处理.虽然FireFox和IE7以上的IE浏览器已经支持透明的PNG图片,但是就IE5-IE6而言还是 ...

  4. 黑马程序员-- C语言交换两个整数变量值几种函数比较

    总结了C语言中几种交换两个整数数值的函数,欢迎交流 #include <stdio.h> 使用多种交换变量值的函数比较 方法一:使用第三方临时变量 这种函数a,b只是值传递,实质上不能修交 ...

  5. 诞生于饭桌上的jcSQL语言

    相信每个Coder都有心在自己求学阶段可以写一门自己的语言,无论是毕业设计,还是课余爱好:不管是为了提升B格,还是想练手,抑或对其他语言不满,想自己撸一个,只要坚持下去了,都是不错的理由. 现在正值暑 ...

  6. J2SE知识点摘记(十二)

    1.      File类 下面的构造方法可以用来生成File对象 File(String directoryPath) geName()用于返回文件名,getParent()返回父目录名,exist ...

  7. c++ 关于类构造函数的初始化列表

    除了性能问题之外,有些时场合初始化列表是不可或缺的,以下几种情况时必须使用初始化列表 常量成员,因为常量只能初始化不能赋值,所以必须放在初始化列表里面 引用类型,引用必须在定义的时候初始化,并且不能重 ...

  8. uestc Palindromic String

    字符串hash因为如果一个字符串是回文串,那么正着做哈希和反着做哈希结果应该一样.于是我们先正反各做一边哈希.如果判断出来一个字符串是回文穿那么这个字符串的前半部分和后半部分的重数一定相同,于是当前位 ...

  9. [LeetCode][Python]15:3Sum

    # -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 15: 3Sumhttps://oj.leetcode.com/problem ...

  10. iso-开发基础知识-1-程序流程

    main-应用程序委托-视图控制器 main()---主函数 应用程序委托  ---AppDelegate     视图控制器 ---ViewController - (BOOL)applicatio ...