上篇文章完成了簡書文章列表數據的瀑布流顯示涧窒。這篇文章將介紹展示點擊單個item文章的的詳情顯示。本來我也想用之前解析HTML源碼的方式原生顯示詳情,但是發(fā)現(xiàn)詳情不同于列表數據有規(guī)律性,正則去匹配的話相當麻煩,所以作罷房揭,用H5直接展示。原生畢竟是網頁的內容晌端,會有很多無用信息捅暴,如廣告內容、跳轉APP咧纠、登陸注冊信息等蓬痒。所以要注入js隱藏它們或者禁用js事件等。
因為WKWebView的性能明顯優(yōu)于UIWebView漆羔,所以本文我們選用WKWebView梧奢。至于怎么初始化WKWebView就不多講了,因為要注入JS代碼有時候要返回一些信息給weView演痒,所以必須使用WKWebViewConfiguration這個東西亲轨,初始化后有調用添加和移除方法來完成js與WKWebView的交互。
//初始化
var webView:WKWebView = {
let configuration = WKWebViewConfiguration.init()
let preferences = WKPreferences.init()
preferences.javaScriptCanOpenWindowsAutomatically = true
preferences.minimumFontSize = 40.0
configuration.preferences = preferences
let webView = WKWebView.init(frame: CGRect(x: 0, y: 0, width: SCREEN_WIDTH, height: SCREEN_HEIGHT - 49 - (IsFullScreen ? 34 : 0)), configuration:configuration)
return webView
}()
注入JS代碼相應時間后如若要回調某些信息一定要在js代碼中和swift代碼中都添加方法鸟顺,在釋放webview的時候需要移除removeScriptMessageHandler惦蚊。
//比如js中添加方法hidOpenInApp
function hidOpenInApp(){
var divs = document.getElementsByClassName("meta");
for (var i = 0;i < divs.length; i ++){
var div = divs[i].innerHTML;
//替換字符串“App中閱讀”為空字符串,達到隱藏的目的
document.getElementsByClassName("meta")[i].innerHTML = div.replace(/App中閱讀/g, "")
}
if (divs.length > 1){
window.webkit.messageHandlers.hidOpenInApp.postMessage(divs.length);
}
}
hidOpenInApp();
//swif中viewWillAppear中要相應添加同名方法
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
self.webView.configuration.userContentController.add(self, name: "hidOpenInApp")
}
//swif中viewDidDisappear中要移除同名方法
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(true)
self.webView.configuration.userContentController.removeScriptMessageHandler(forName: "hidOpenInApp")
}
至于在哪里注入?首先肯定是要在網頁加載完后注入js蹦锋,但是對于動態(tài)網頁曾撤,就算走了didFinish的方法,也可能沒有完全加載出來晕粪,沒加載出來去操作document自然是沒效果的。很多時候就算WebView上滑的時候也就scrollView.contentOffset.y的值發(fā)生變化的時候會加載新內容渐裸,這個時候就需要監(jiān)聽scrollView.contentOffset.y值的變化巫湘,達到某個值的時候再注入JS代碼。
//MARK: - --- webview加載完成
//網頁一次性加載完顯示的內容昏鹃,屬性能被檢測的情況下直接在didFinish方法中注入
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
self.topIndicator?.stopAnimating()
//如果不是列表傳來的URL不做js注入
if self.urlStr != "\(self.webView.url!)" {return}
//加載項目內 js文件尚氛,注入js代碼
let doc = ReadData("InjectionCode", "js")
print(doc)
self.webView.evaluateJavaScript(doc, completionHandler: { (htmlStr, error) in
if error != nil {
print(error!)
}else if (htmlStr != nil){
print(htmlStr!)
}
})
}
// =============================================================
/** 讀取項目本地文件數據 */
func ReadData(_ fileName:String, _ type:String) -> String {
let path = Bundle.main.path(forResource: fileName, ofType: type)
let url = URL(fileURLWithPath: path!)
let data = try! Data(contentsOf: url)
return String.init(data: data, encoding: .utf8)!
}
上面注入hidOpenInApp方法的地方應該是在scrollView的代理方法scrollViewDidScroll中,至于scrollView.contentOffset.y > 1000這個值是我認為設定洞渤,不一定是視圖剛出現(xiàn)時的偏移量
//MARK: - --- 監(jiān)聽滑動偏移量
func scrollViewDidScroll(_ scrollView: UIScrollView) {
//print(scrollView.contentOffset.y)
//如果不是列表傳來的URL不做js注入
if self.urlStr != "\(self.webView.url!)" {return}
//隱藏“App中閱讀”字樣
if scrollView.contentOffset.y > 1000 {
if self.appWordsHid == true {return}
let doc =
"""
function hidOpenInApp(){
var divs = document.getElementsByClassName("meta");
for (var i = 0;i < divs.length; i ++){
var div = divs[i].innerHTML;
//替換字符串“App中閱讀”為空字符串阅嘶,達到隱藏的目的
document.getElementsByClassName("meta")[i].innerHTML = div.replace(/App中閱讀/g, "")
}
if (divs.length > 1){
window.webkit.messageHandlers.hidOpenInApp.postMessage(divs.length);
}
}
hidOpenInApp();
"""
self.webView.evaluateJavaScript(doc, completionHandler: { (htmlStr, error) in
if error != nil {
print(error!)
}else if (htmlStr != nil){
print(htmlStr!)
}
})
}
}
大致的注入方法知道了,就是分析HTML源碼载迄,注入JS代碼讯柔,達到想要的效果。
1.隱藏
因為demo沒做登陸护昧,故跟賬號有關的都會隱藏魂迄,還有打開簡書APP類似的字樣和弄能也會隱藏屏蔽,下面列舉了一些惋耙。
//隱藏視圖
function hidViews(){
//隱藏頂部信息
document.getElementsByClassName("header-wrap")[0].style.display = "none";
//隱藏“打開APP”
document.getElementsByClassName("app-open")[0].style.display = "none";
//隱藏打開簡書APP按鈕
document.getElementsByClassName("open-app-btn")[0].style.display = "none";
//隱藏底部
document.getElementById("footer").style.display = "none";
//隱藏喜歡按鈕
document.getElementsByClassName("like-btn")[0].style.display = "none";
//輸出正文內容
let mainBody = document.getElementsByClassName("collapse-free-content")[0].outerHTML
window.webkit.messageHandlers.hidViews.postMessage(mainBody);
};
hidViews();
2.創(chuàng)建標簽
因為上面圖1的②框選部分點擊會跳轉捣炬,而分析源碼會a就算去掉href的內容也同樣達不到屏蔽跳轉的效果,我就嘗試“曲線救國”绽榛,創(chuàng)建div標簽覆蓋在上面湿酸,可以達到屏蔽跳轉事件的效果。
//移除頭部作者信息的href屬性(想禁止a標簽的跳轉灭美,無果)
//var bObj = document.getElementsByClassName("article-info")[0].getElementsByClassName("info")[0];
//bObj.href = "javascript:void(0);";
//bObj.onclick = "js_method();return false;";
//bObj.removeAttribute("href")
//創(chuàng)建一個定位的覆蓋層間 接阻止a標簽的跳轉
function createView(){
var div = document.getElementsByClassName("article-info")[0];
div.style.position = "relative";
var childDiv = document.createElement("div");
childDiv.id = "cover-div";
//childDiv.style.background = "red";
childDiv.style.position = "absolute";
childDiv.style.top = "0";
childDiv.style.left = "0";
childDiv.style.right = "0";
childDiv.style.bottom = "0";
//childDiv.innerHTML=" i am a append div !"
div.appendChild(childDiv);
window.webkit.messageHandlers.createView.postMessage("Success");
}
createView();
要更好的達到自己預期的效果推溃,熟悉前端的JS、HTML冲粤、CSS都能達到事半功倍的效果美莫。只需要明白在哪個地方注入JS,哪個地方回調梯捕,其余就是前端的知識了厢呵。
如果想要了解詳詳細步驟的可以戳下面??GitHub鏈接下載demo,里面都有詳細的注釋傀顾,下載下來跑一遍打打斷點不明白的一下就懂了襟铭。
本文GitHub源碼
如果還有什么不懂,可以在下方評論區(qū)留言,謝謝閱讀寒砖。
上篇文章:瀑布流展示/切換簡書列表數據