iOS Safari阅读模式研究

这是一篇在2013年准备的资料,现在分享出来,供有需要的同学参考。

要点

(1) 阅读模式的检测

在frame加载完成后,触发一个timer来检测是否可以使用阅读模式。检测的方式是使用JavaScriptCore framework的接口执行一段JS脚本,然后取JS中属性值来判断是否可以进入阅读模式。如果当前页面可以进入阅读模式,将在地址栏显示阅读模式切换按钮。

(2) 阅读模式的执行

  当用户点击阅读模式切换按钮时,会依次执行:

i. 执行阅读模式检查脚本,判断目前是否可以进入阅读模式。

ii. 创建WebView并加载阅读模式页面的HTML页面,iPad下为Reader~iPad.html .

iii. 在页面允许修改Window对象的位置,执行阅读模式处理脚本。

v. 显示页面

(3) 阅读模式页面的控制

 Safari实现了几个类来处理阅读模式的显示和操作。

主要涉及的类

TabDocument代表了一个页签下的页面文档,这里有页面的主要控制操作和阅读模式的控制操作(ReaderControllerDelegate)。

BrowserReaderView是负责阅读模式页面显示的类。

阅读模式检测的序列图

下面是一个在正常页面加载后触发TabDocument_readerAvailabilityDetectionTimer的序列图:

除此之外,另外两个函数-[BrowserController stopFromAddressView:]-[TabDocument _progressDidStall] 也会触发阅读模式检测的执行。

当Timer触发后会开始真正执行脚本:

JSEvaluateScript,JSObject等都是JavaScriptCore framework提供的接口。

执行完成脚本,会执行回调函数-[TabDocument _didDetectReaderAvailability:]将把脚本中的ReaderArticleFinder.isReaderModeAvailable的值传入,再根据这个值判断是否要显示阅读模式按钮。

阅读模式的显示

当点击阅读模式按钮时,下图的2.1是重新发起检测脚本的执行,步骤2.2则开始加载显示阅读模式。

WebView放出一个接口webView:didClearWindowObject:forFrame,允许用户修改全局对象, Safari就是在这个位置提前于页面真正加载就去执行阅读模式处理脚本,然后在页面加载完时会依据下面的写法,执行ReaderJS.loaded(),显示页面内容。

<body class="preloading" onscroll="articleHasScrolled();">

ReaderJS就是阅读模式内容抽取脚本中的对象。

下面是执行阅读模式内容抽取的脚本执行过程:

*这是Apple关于webView:didClearWindowObject:forFrame的说明:

Use this method to set custom properties on the window object before the page is actually loaded. Every time a frame loads or is reloaded all DOM properties are cleared from the window object so the new page has a fresh window object to use. If the page you are loading depends on specific window object properties to exist, they should be added at this point before any scripts are executed.

附上三个使用到文件,分别是:

Reader~ipad.html iPad下使用的阅读模式页面html文件

safari_reader_check.js 阅读模式检测JS脚本

safari_reader_clicked.js 阅读模式内容抽取JS脚本

到GitHub上查看,链接:iOSSafariReaderMode

参考

. 分析的过程记录

时间: 2024-10-13 19:59:33

iOS Safari阅读模式研究的相关文章

【转】 iOS DES ECB模式对称加密解密

最近忙于android和iOS的项目,写完了android的DES 的ECB模式加密解密(相关连接:http://blog.csdn.net/vipa1888/article/details/8086037),又 回到了Ios上面,因为本人也是最近今年开始研究ios的,所以Ios上面好多东西都不懂,进过了半年的研究,终于吧ios的DES 的ECB模式对称加密解密搞定了,本人遇到的问题很严重的问题,网上写的好多16进制数转化位字节都有问题的,经过本人研究发现他们有一个地方写错了,导 致解密后的NS

localStorage与sessionStorage在safari无痕模式下的情况

localStorage与sessionStorage都是非常好用的h5新特性,当localStorage在iOS Safari.chrome和UC浏览器中的隐私模式(也叫无痕模式)下是无法使用的,会出现如下情况: 这样看来在无痕模式下,localStorage和sessionStorage都是存在的,只是浏览器没有配额存放相关的缓存数据.如果项目不考虑无痕模式的情况,用这二个新特性还是非常好用的,否则还是酌情使用.

iOS应用导航模式

原文:http://www.leiphone.com/news/201406/0726-warlial-iosnavigation.html iOS应用导航模式有3种:平铺列表.标签页.树状结构,每种模式都配有不同的工具栏和控件.三种导航模式可以独立使用也可以混搭. 平铺列表:由scrollView和pageControl组合而成的展示方式. 这种方式主要用于只有一个主屏的简单应用.向左右滑动即可翻页,典型应用比如内置的天气应用. 当然,平铺列表式导航也可以根据你的需要随意的添加.删除卡片.从某

iPad横屏模式研究

在iPad应用开发时如何让设备只支持横屏(landscape)模式,我做了多次尝试,并没有发现比较简捷的设置方法.我尝试了大概大概3种方式. 1.通过XCode设置“iPad Deployment info”,只选择横屏左和横屏右,部署测试后并没有生效,这种方法实质是在xxx_info.plist项目配置文件中添加如下信息: <key>UISupportedInterfaceOrientations~ipad</key> <array> <string>UI

神奇的网页阅读模式

今天突然之间发现了一个网页中含有阅读模式,打开之后网页中的所有广告被屏蔽掉了,确实非常的舒服,看网页的感觉就像看书一样.可以这个功能究竟是什么回事呢? 操作步骤: 1.在浏览器中输入,about:config 2.搜索 reader.parse-on-load.enabled,确定值为“true”即可 注意事项: 有部分人,可能会神奇的发现有些页面是看不到阅读模式的,这是什么原因呢?这是因为该页面本身不支持阅读模式导致,并非浏览器本身的问题.目前火狐.谷歌等浏览器好像都支持这个功能了.其实这个功

【IOS 开发】IOS 开发 简介 (IOS项目文件 | MVC 模式 | 事件响应机制 | Storyboard 控制界面 | 代码控制界面 | Retina 屏幕图片适配)

一. IOS 项目简介 1. IOS 文件简介 创建一个 HelloWorld 项目, 在这个 IOS 项目中有四个目录 : 如下图; -- HelloWorldTests 目录 : 单元测试相关的类和资源; (1) HelloWorld 目录 HelloWorld 目录介绍 : -- 命名规则 : 该目录名称与 IOS 项目名称相同, 是主目录; -- 存放内容 : IOS 项目的 源码文件, 界面设计文件, 资源文件都存放在该目录下; -- 源文件 : Objective C 的 .m 和

解决IOS safari在input focus弹出输入法时不支持position fixed的问题

该文章为转载 我们在做移动web应用的时候,常常习惯于使用position:fixed把一个input框作为提问或者搜索框固定在页面底部.但在IOS的safari和webview中,对position:fixed的支持不是很好(在IOS5之前甚至还不支持position:fixed).我遇到的其中一个问题就是,在iOS6+环境下,input focus弹出输入法的时候,设置了position fixed的input框浮在页面上了,而不是吸附在软键盘上.效果如图(图片来源于网上): 而Androi

iOS多线程的初步研究(一)-- NSThread

iOS多线程的初步研究(一)-- NSThread 对于多线程的开发,iOS系统提供了多种不同的接口,先谈谈iOS多线程最基础方面的使用.产生线程的方式姑且分两类,一类是显式调用,另一类是隐式调用. 一.显示调用的类为NSThread.一般构造NSThread的线程对象可通过两种方式: 1. 初始化线程主方法: [NSThread detachNewThreadSelector:@selector(run:) toTarget:target withObject:obj];//类方法 或 NST

iOS多线程的初步研究(四)-- NSTimer

 iOS多线程的初步研究(四)-- NSTimer 原文地址  http://www.cnblogs.com/sunfrog/p/3243230.html 理解run loop后,才能彻底理解NSTimer的实现原理,也就是说NSTimer实际上依赖run loop实现的. 先看看NSTimer的两个常用方法: + (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelec