美文网首页
JavaScript与原生交互

JavaScript与原生交互

作者: 今晚月色 | 来源:发表于2019-03-29 09:18 被阅读0次
    实例样式

    原生页面与HTML页面进行相互调用

    方式 适用对象
    拦截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>原生注入数据</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调用- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType方法,判断获取的Url地址

    // 调用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;
    } 
    // 注入数据给JS
    if ([request.URL.absoluteString hasSuffix:@"getText"]) { 
        [webView stringByEvaluatingJavaScriptFromString:@"getText('哈哈')"];
         return NO;
    }
    return YES;
    

    WKWebView

    遵循WKNavigationDelegate调用- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler方法判断获取的地址

    NSString *strRequest = [navigationAction.request.URL.absoluteString stringByRemovingPercentEncoding];
    // 调用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"]) { // 注入数据给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>并实现- (void)webViewDidFinishLoad:(UIWebView *)webView方法。
    // 对JSContext对象进行初始化
    JSContext *context = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    // 验证JSContext对象是否初始化成功
    context.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue){
        context.exception = exceptionValue;
    };
     
    // 调用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];
    };
     
    // 注入数据给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. 实现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 {
        // 调用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;
        }
        
        // 注入数据给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>注入数据</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关联
    _bridge = [WebViewJavascriptBridge bridgeForWebView:self.webView];
    
    [_bridge setWebViewDelegate:self];
    
    1. 调用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. 注入数据
    [_bridge registerHandler:@"getTextClick" handler:^(id data, WVJBResponseCallback responseCallback) {
            responseCallback(@"哈哈哈");
    }];
    

    相关文章

      网友评论

          本文标题:JavaScript与原生交互

          本文链接:https://www.haomeiwen.com/subject/nuykbqtx.html