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. 導入<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. 導入頭文件#import <WebViewJavascriptBridge.h>
  3. 聲明方法@property WebViewJavascriptBridge* bridge;
  4. 與WebView關聯(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(@"哈哈哈");
}];
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容