Swift-WKWebView與JS交互處理H5頁面問題

上篇文章完成了簡書文章列表數據的瀑布流顯示涧窒。這篇文章將介紹展示點擊單個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類似的字樣和弄能也會隱藏屏蔽,下面列舉了一些惋耙。


圖1

圖2
//隱藏視圖
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ū)留言,謝謝閱讀寒砖。
上篇文章:瀑布流展示/切換簡書列表數據

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末赐劣,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子哩都,更是在濱河造成了極大的恐慌魁兼,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件漠嵌,死亡現(xiàn)場離奇詭異咐汞,居然都是意外死亡,警方通過查閱死者的電腦和手機儒鹿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進店門化撕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人约炎,你說我怎么就攤上這事植阴。” “怎么了圾浅?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵掠手,是天一觀的道長。 經常有香客問我贱傀,道長惨撇,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任府寒,我火速辦了婚禮魁衙,結果婚禮上,老公的妹妹穿的比我還像新娘株搔。我一直安慰自己剖淀,他們只是感情好,可當我...
    茶點故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布纤房。 她就那樣靜靜地躺著纵隔,像睡著了一般。 火紅的嫁衣襯著肌膚如雪炮姨。 梳的紋絲不亂的頭發(fā)上捌刮,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天,我揣著相機與錄音舒岸,去河邊找鬼晰筛。 笑死猖吴,一個胖子當著我的面吹牛乒验,可吹牛的內容都是我干的。 我是一名探鬼主播个少,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼眯杏!你這毒婦竟也來了夜焦?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤岂贩,失蹤者是張志新(化名)和其女友劉穎茫经,沒想到半個月后,有當地人在樹林里發(fā)現(xiàn)了一具尸體萎津,經...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡科平,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了姜性。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,688評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡髓考,死狀恐怖部念,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情氨菇,我是刑警寧澤儡炼,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站查蓉,受9級特大地震影響乌询,放射性物質發(fā)生泄漏。R本人自食惡果不足惜豌研,卻給世界環(huán)境...
    茶點故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一妹田、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧鹃共,春花似錦鬼佣、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至阴孟,卻和暖如春晌纫,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背永丝。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工锹漱, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人类溢。 一個月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓凌蔬,卻偏偏與公主長得像露懒,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子砂心,可洞房花燭夜當晚...
    茶點故事閱讀 44,573評論 2 353

推薦閱讀更多精彩內容

  • 1懈词、通過CocoaPods安裝項目名稱項目信息 AFNetworking網絡請求組件 FMDB本地數據庫組件 SD...
    陽明先生_X自主閱讀 15,979評論 3 119
  • 今天是周二,節(jié)后第一天上班辩诞,路上那叫一個忙呀坎弯。車連著車,車挨著車译暂,一輛接一輛抠忘,車水馬龍、川流不息外永、水泄不通...
    寒梅hm閱讀 228評論 0 3
  • 莫愁湖畔莫愁女崎脉,滿眼哀傷淚迷離〔ィ可恨心中出征人囚灼,今世可曾有歸期?
    十三度空間閱讀 267評論 0 0