JavaScript與原生交互

實例樣式

原生頁面與HTML頁面進行相互調(diào)用

方式 適用對象
攔截URL UIWebViewWKWebView
JavaScriptCore UIWebView
MessageHandler WKWebView
WebViewJavascriptBridge UIWebViewWKWebView

實例HTML代碼

    <body>
        <h2>按鈕點擊</h2>
        <button type="submit" onclick="buttonEvent()" id="submitButto">提交</button>
        <h2>文件上傳</h2>
        <input type="file" />
        <h2>原生注入數(shù)據(jù)</h2>
        <input type="text" id="textField">
        <input type="button" onclick="getTextEvent()" value="開始注入">
        <script>
            function loadURL(url) {
                var iFrame;
                iFrame = document.createElement("iframe");
                iFrame.setAttribute("src", url);
                iFrame.setAttribute("style", "display:none;");
                iFrame.setAttribute("height", "0px");
                iFrame.setAttribute("width", "0px");
                iFrame.setAttribute("frameborder", "0");
                document.body.appendChild(iFrame);
                iFrame.parentNode.removeChild(iFrame);
                iFrame = null;
            }
            function buttonEvent(){
                loadURL("/buttonEvent");
                buttonDidPapped();
            }
        
            function getTextEvent() {
                loadURL("/getText");
                getTextButtonDidPapped();
            }
            function getText(text){
                document.getElementById("textField").value = text;
            }
        </script>
    </body>       

攔截URL

UIWebView

遵循UIWebViewDelegate調(diào)用- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType方法盼理,判斷獲取的Url地址

// 調(diào)用JS
if ([request.URL.absoluteString hasSuffix:@"buttonEvent"]) {
    UIAlertController *vc = [UIAlertControlleralertControllerWithTitle:@"溫馨提示" message:@"點擊了提交按鈕" preferredStyle:UIAlertControllerStyleAlert];
        [vc addAction:[UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            
    }]];
    [self presentViewController:vc animated:true completion:nil];  
    return NO;
} 
// 注入數(shù)據(jù)給JS
if ([request.URL.absoluteString hasSuffix:@"getText"]) { 
    [webView stringByEvaluatingJavaScriptFromString:@"getText('哈哈')"];
     return NO;
}
return YES;

WKWebView

遵循WKNavigationDelegate調(diào)用- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler方法判斷獲取的地址

NSString *strRequest = [navigationAction.request.URL.absoluteString stringByRemovingPercentEncoding];
// 調(diào)用JS
if ([strRequest hasSuffix:@"buttonEvent"]) {
    UIAlertController *vc = [UIAlertController alertControllerWithTitle:@"溫馨提示" message:@"點擊了提交按鈕" preferredStyle:UIAlertControllerStyleAlert];
    [vc addAction:[UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            
    }]];
    [self presentViewController:vc animated:true completion:nil];
    decisionHandler(WKNavigationActionPolicyCancel);
} else if ([strRequest hasSuffix:@"getText"]) { // 注入數(shù)據(jù)給JS
    [webView evaluateJavaScript:@"getText('哈哈')" completionHandler:^(id _Nullable info, NSError * _Nullable error) {
        NSLog(@"Error--%@, info--%@", error, info);
    }];
    decisionHandler(WKNavigationActionPolicyCancel);
} else {
    decisionHandler(WKNavigationActionPolicyAllow);
}

JavaScriptCore

  1. 導(dǎo)入<JavaScriptCore/JavaScriptCore.h>
  2. 遵循<UIWebViewDelegate>并實現(xiàn)- (void)webViewDidFinishLoad:(UIWebView *)webView方法。
// 對JSContext對象進行初始化
JSContext *context = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
// 驗證JSContext對象是否初始化成功
context.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue){
    context.exception = exceptionValue;
};
 
// 調(diào)用JS  
context[@"buttonDidPapped"] = ^{
    UIAlertController *vc = [UIAlertController alertControllerWithTitle:@"溫馨提示" message:@"點擊了提交按鈕" preferredStyle:UIAlertControllerStyleAlert];
    [vc addAction:[UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            
    }]];
    [self presentViewController:vc animated:true completion:nil];
};
 
// 注入數(shù)據(jù)給JS   
context[@"getTextButtonDidPapped"] = ^{
    dispatch_async(dispatch_get_main_queue(), ^{
      [self.webView stringByEvaluatingJavaScriptFromString:@"getText('哈哈')"];
        });
};

MessageHandler

  1. 修改js中的方法俄删, 通過window.webkit.messageHandlers+操作方法
function buttonEvent(){
    window.webkit.messageHandlers.buttonEvent.postMessage(null);
}
        
function getTextEvent() {
    window.webkit.messageHandlers.getTextEvent.postMessage(null);
}
  1. 遵循WKScriptMessageHandler
  2. - (void)viewWillAppear:(BOOL)animated中添加scriptMessageHandler
  3. - (void)viewWillDisappear:(BOOL)animated中移除scriptMessageHandler
  4. 實現(xiàn)WKScriptMessageHandler方法
- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self.webView.configuration.userContentController addScriptMessageHandler:self name:@"buttonEvent"];
    [self.webView.configuration.userContentController addScriptMessageHandler:self name:@"getTextEvent"];
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"buttonEvent"];
    [self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"getTextEvent"];
}

#pragma mark - WKScriptMessageHandler Method
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
    // 調(diào)用JS
    if ([message.name isEqualToString:@"buttonEvent"]) {
        UIAlertController *vc = [UIAlertController alertControllerWithTitle:@"溫馨提示" message:@"點擊了提交按鈕" preferredStyle:UIAlertControllerStyleAlert];
        [vc addAction:[UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            
        }]];
        [self presentViewController:vc animated:true completion:nil];
        return;
    }
    
    // 注入數(shù)據(jù)給JS
    if  ([message.name isEqualToString:@"getTextEvent"]) {
        [self.webView evaluateJavaScript:@"getText('哈哈')" completionHandler:^(id _Nullable info, NSError * _Nullable error) {
            NSLog(@"Error--%@, info--%@", error, info);
        }];
        return;
    }
}

WebViewJavascriptBridge

HTML代碼

<body>
    <h2>按鈕點擊</h2>
    <input id = 'submitBtn' type="button" value="提交按鈕" onclick="submitClick()"/>
    <h2>文件選擇</h2>
    <input type="file" id="image">
    <h2>注入數(shù)據(jù)</h2>
    <input type="text" id="getTextField" />
    <input type="button" value="開始獲取" id = 'startGet' onclick="getTextClick()"/>
    <script>
        function setupWebViewJavascriptBridge(callback) {
            if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); }
            if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); }
            window.WVJBCallbacks = [callback];
            var WVJBIframe = document.createElement('iframe');
            WVJBIframe.style.display = 'none';
            WVJBIframe.src = 'https://__bridge_loaded__';
            document.documentElement.appendChild(WVJBIframe);
            setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0)
        }

        setupWebViewJavascriptBridge(function(bridge) {

        })

        function submitClick() {
            WebViewJavascriptBridge.callHandler('submitClick', null, function(response) {
                
            });
        }
        function getTextClick() {
            WebViewJavascriptBridge.callHandler('getTextClick', null, function(response) {
                document.getElementById("getTextField").value = response;
            });
        }
    </script>
</body>

第三方庫:地址

  1. 添加WebViewJavascriptBridge
  2. 導(dǎo)入頭文件#import <WebViewJavascriptBridge.h>
  3. 聲明方法@property WebViewJavascriptBridge* bridge;
  4. 與WebView關(guān)聯(lián)
_bridge = [WebViewJavascriptBridge bridgeForWebView:self.webView];

[_bridge setWebViewDelegate:self];
  1. 調(diào)用js
[_bridge registerHandler:@"submitClick" handler:^(id data, WVJBResponseCallback responseCallback) {
        UIAlertController *vc = [UIAlertController alertControllerWithTitle:@"溫馨提示" message:@"點擊了提交按鈕" preferredStyle:UIAlertControllerStyleAlert];
        [vc addAction:[UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            
        }]];
        [self presentViewController:vc animated:true completion:nil];
}];
  1. 注入數(shù)據(jù)
[_bridge registerHandler:@"getTextClick" handler:^(id data, WVJBResponseCallback responseCallback) {
        responseCallback(@"哈哈哈");
}];
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末宏怔,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子畴椰,更是在濱河造成了極大的恐慌臊诊,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件迅矛,死亡現(xiàn)場離奇詭異妨猩,居然都是意外死亡,警方通過查閱死者的電腦和手機秽褒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進店門壶硅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來威兜,“玉大人,你說我怎么就攤上這事庐椒〗范妫” “怎么了?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵约谈,是天一觀的道長笔宿。 經(jīng)常有香客問我,道長棱诱,這世上最難降的妖魔是什么泼橘? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮迈勋,結(jié)果婚禮上炬灭,老公的妹妹穿的比我還像新娘。我一直安慰自己靡菇,他們只是感情好重归,可當我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著厦凤,像睡著了一般鼻吮。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上较鼓,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天椎木,我揣著相機與錄音,去河邊找鬼笨腥。 笑死拓哺,一個胖子當著我的面吹牛勇垛,可吹牛的內(nèi)容都是我干的脖母。 我是一名探鬼主播,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼闲孤,長吁一口氣:“原來是場噩夢啊……” “哼谆级!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起讼积,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤肥照,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后勤众,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體舆绎,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年们颜,在試婚紗的時候發(fā)現(xiàn)自己被綠了吕朵。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片猎醇。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖努溃,靈堂內(nèi)的尸體忽然破棺而出硫嘶,到底是詐尸還是另有隱情,我是刑警寧澤梧税,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布沦疾,位于F島的核電站,受9級特大地震影響第队,放射性物質(zhì)發(fā)生泄漏哮塞。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一凳谦、第九天 我趴在偏房一處隱蔽的房頂上張望彻桃。 院中可真熱鬧,春花似錦晾蜘、人聲如沸邻眷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽肆饶。三九已至,卻和暖如春岖常,著一層夾襖步出監(jiān)牢的瞬間驯镊,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工竭鞍, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留板惑,地道東北人。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓偎快,卻偏偏與公主長得像冯乘,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子晒夹,可洞房花燭夜當晚...
    茶點故事閱讀 44,933評論 2 355