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
的順序圖表:
vcWxvjo8YnIgLz4NCjxpbWcgYWx0PQ=="sequence #2" src="http://www.bkjia.com/uploads/allimg/160324/0416021944-2.png" title="\" />
JSEvaluateScript
,JSObject
等都是JavaScriptCore framework提供的介面。
執行完成指令碼,會執行回呼函數-[TabDocument _didDetectReaderAvailability:]
將把指令碼中的ReaderArticleFinder.isReaderModeAvailable
的值傳入,再根據這個值判斷是否要顯示閱讀模式按鈕。
閱讀模式的顯示
當點擊閱讀模式按鈕時,的2.1是重新發起檢測指令碼的執行,步驟2.2則開始載入顯示閱讀模式。
WebView放出一個介面webView:didClearWindowObject:forFrame
,允許使用者修改全域對象, Safari就是在這個位置提前於頁面真正載入就去執行閱讀模式處理指令碼,然後在頁面載入完時會依據下面的寫法,執行ReaderJS.loaded()
,顯示頁面內容。
ReaderJS
就是閱讀模式內容抽取指令碼中的對象。
下面是執行閱讀模式內容抽取的指令碼執行過程:
html iPad下使用的閱讀模式頁面html檔案
safari_reader_check.js
閱讀模式檢測JS指令碼
safari_reader_clicked.js
閱讀模式內容抽取JS指令碼