简体   繁体   English

WKWebView中未执行JavaScript

[英]JavaScript not executed in WKWebView

Since I'm going a bit crazy with this one, I've decided to give it another try and post about it here. 由于我对此感到有些疯狂,因此我决定再次尝试将其发布在此处。

So... 所以...

I have a simple Swift/Cocoa application with a WKWebView in it. 我有一个带有WKWebView的简单Swift / Cocoa应用程序。

I load a local HTML file (which - along with the rest of the .css/.js dependencies - is being copied to the bundle inside a /web folder). 我加载了一个本地HTML文件(与其他.css / .js依赖项一起,将其复制到/web文件夹中的分发包中)。

Here's the complete code: 这是完整的代码:

<!DOCTYPE html>
<html>
    <head>
        <title>IBAN Validator</title>
        <meta name="viewport" content="width=device-width"/>
        <meta charset="UTF-8">

        <link href="style/font-awesome.min.css" type="text/css" rel="stylesheet"/>
        <link href="style/electriq.css" type="text/css" rel="stylesheet"/>
        <link href="style/custom.css" type="text/css" rel="stylesheet" />
    </head>
    <body>
        <!-- window/ -->
        <div class="window">
            <div class="content" style="text-align: center">
                <div class="panel">
                    <input id="iban" type="text" style="text-align:center;"><br/>
                    <div style="position: relative; max-width: 150px; width: 100%; margin: 0 auto">
                        <a id="validateButton" href="#" class="button" style="width:150px;">Validate</a>
                        <span id="resultValid" style="position:absolute; left: calc(100% + 20px); top: 10%; color: green; font-size: 20px; display:none;"><i class="fa fa-check"></i></span>
                        <span id="resultInvalid" style="position:absolute; left: calc(100% + 20px); top: 10%; color: red; font-size: 20px; display:none;"><i class="fa fa-close"></i></span>
                    </div>
                </div>
            </div>
        </div>
        <!-- /window -->

        <div id="loader_overlay" style="padding-top:10%">
            <i class="fa fa-circle-o-notch fa-spin fa-3x fa-fw"></i><br/>
        </div>

        <!-- scripts/ -->
        <script>if (typeof module === 'object') {window.module = module; module = undefined;}</script>
        <script src="jquery.min.js" type="text/javascript"></script>
        <script>
            if (typeof window.jQuery !== 'undefined') {
                window.document.getElementById("loader_overlay").innerHTML += ".";
            } else {
                window.document.getElementById("loader_overlay").innerHTML += "x";
            }
        </script>
        <script src="handlebars.min.js" type="text/javascript"></script>
        <script>
            if (typeof window.Handlebars !== 'undefined') {
                window.document.getElementById("loader_overlay").innerHTML += ".";
            } else {
                window.document.getElementById("loader_overlay").innerHTML += "x";
            }
        </script>
        <script src="bridgecommander.js" type="text/javascript"></script>
        <script>
            if (typeof window.BridgeCommander !== 'undefined') {
                window.document.getElementById("loader_overlay").innerHTML += ".";
            } else {
                window.document.getElementById("loader_overlay").innerHTML += "x";
            }
        </script>
        <script src="iban.js" type="text/javascript"></script>
        <script>
            if (typeof window.IBAN !== 'undefined') {
                window.document.getElementById("loader_overlay").innerHTML += ".";
            } else {
                window.document.getElementById("loader_overlay").innerHTML += "x";
            }
        </script>
        <!-- <script src="app.js" type="text/javascript"></script> -->
        <script>

            // Generated by CoffeeScript 2.0.2
            var doValidate;

            window.appLoaded = true;
            window.document.getElementById("loader_overlay").innerHTML += ".";
            BridgeCommander.call("echo", "Before: onload");
            window.document.getElementById("loader_overlay").innerHTML += ".";

            window.onload = function() {
              BridgeCommander.call("echo", "Inside: onload");
              document.getElementById("loader_overlay").style.display = 'none';
              return $("#validateButton").on("click", doValidate);
            };
            window.document.getElementById("loader_overlay").innerHTML += ".";
            BridgeCommander.call("echo", "After: onload");

            doValidate = function() {
              var iban, valid;
              iban = $("#iban").val();
              valid = IBAN.isValid(iban);
              if (valid) {
                $("#resultValid").show();
                $("#resultInvalid").hide();
                $("#validateButton").removeClass("invalid").addClass("valid");
                BridgeCommander.call("echo", `Validating: ${iban}, Result: valid`);
              } else {
                $("#resultValid").hide();
                $("#resultInvalid").show();
                $("#validateButton").removeClass("valid").addClass("invalid");
                BridgeCommander.call("echo", `Validating: ${iban}, Result: invalid`);
              }
              setTimeout(function() {
                $("#validateButton").removeClass("valid").removeClass("invalid");
                $("#resultValid").hide();
                return $("#resultInvalid").hide();
              }, 3000);
              return false;
            };
            window.document.getElementById("loader_overlay").innerHTML += ".";

            if (typeof window.appLoaded !== 'undefined') {
                window.document.getElementById("loader_overlay").innerHTML += ".";
            } else {
                window.document.getElementById("loader_overlay").innerHTML += "x";
            }
        </script>
        <script>if (window.module) module = window.module;</script>
        <!-- /scripts -->
    </body>

</html>

Important Note: Here (meaning on my Mac - and everyone's Mac with 10.3.1 I've tried this on) everything works fine. 重要说明: 在这里(意味着在我的Mac上-以及我尝试过的所有装有10.3.1的Mac上的Mac),一切正常。 When I upload the exact same binary to the App Store for review, I keep getting the same "error" screenshot, signifying none of the code within my last <script></script> block gets executed. 当我将完全相同的二进制文件上载到App Store进行审查时,我不断得到相同的“错误”屏幕截图,表示最后一个<script></script>块中的任何代码均未执行。 (after the window.appLoaded = true part) . (在window.appLoaded = true部分之后)


What could be going on? 可能会发生什么? I've literally tried anything to debug this (hence, the numerous window.document.getElementById thing, adding dots to make sure everything worked), but still nothing. 我确实尝试了任何方法来调试此问题(因此,使用了许多window.document.getElementById东西,添加了点以确保一切正常),但仍然没有任何效果。

As you can see, I'm loading several scripts (which according to my tests load fine), and I also have several pieces of inline JS code (which still work fine). 如您所见,我正在加载多个脚本(根据我的测试,它们可以正常加载),并且我还具有几段内联JS代码(仍然可以正常运行)。 Except for the last one! 除了最后一个! (which, no matter what, even from an external file, seems to refuse to load...) (无论如何,即使来自外部文件,它似乎也拒绝加载...)

Again, I thought about sth being cached, I don't know, but I remind you that it - apparently -- works everywhere apart from the Review team's machine :S 再说一次,我想到了要缓存的东西,我不知道,但是我提醒你,除了评论小组的机器以外,它显然可以在任何地方工作:

Any idea would be welcome! 任何想法都将受到欢迎!


PS In case something is not clear, please feel free to ask me anything PS:如果不清楚,请随时问我什么


Update: (28/11/2017) Tried the whole thing with a simple - old-style - WebView (in case it had to do with the WKWebView ) and still my app gets rejected. 更新: (28/11/2017)使用简单的旧式WebView尝试了整个过程(以防与WKWebView ),但我的应用仍然被拒绝。 Or to be precise, my app (exact version, same everything) runs fine everywhere, except for the guy that reviews it. 确切地说,我的应用程序(确切的版本,所有内容都一样)在任何地方都可以正常运行,但需要对其进行审核的人除外。

This could be because the browser does not know how to parse the contents of the script tags 这可能是因为浏览器不知道如何解析脚本标签的内容

<script></script> tags require the type attribute on them most browsers will assume it's the same as the last one but as none of your code containing script tags specifies the type it might not know how to parse them the script support more than javascript for example VBScript to whenever you open a <script> for javascript it should be <script type="text/javascript"> <script></script>标记要求在其上使用type属性,大多数浏览器会假定它与上一个相同,但是由于没有包含script标记的代码都指定了它可能不知道如何解析它们的类型,因此script不仅仅支持javascript,例如VBScript ,每次打开javascript的<script>时都应为<script type="text/javascript">

The other problem could be the window.onload I would recommend you change it to the DOMContentLoaded event and use a closure to make sure it executes the code. 另一个问题可能是window.onload我建议您将其更改为DOMContentLoaded事件,并使用闭包确保其执行代码。

More so why are you not loading jQuery in the head tag where it's supposed to be loaded move <script src="jquery.min.js" type="text/javascript"></script> to inside the <head></head> . <script src="jquery.min.js" type="text/javascript"></script>您为什么不将jQuery加载到应该加载的head标签中,将<script src="jquery.min.js" type="text/javascript"></script>移至<head></head>内部<head></head>

Following on from this if you have jQuery why are you mixing jQuery and pure Javascript if you have jQuery use it's smaller code and cleaner 接下来,如果您使用jQuery,为什么要混合使用jQuery和纯Javascript(如果您使用jQuery),则它的代码更小,更简洁

 (function($){
     $(function(){
         window.appLoaded = true;
         $("loader_overlay").append(".");
         BridgeCommander.call("echo", "Before: onload");
         $("loader_overlay").append(".");

         $("loader_overlay").append(".");
         BridgeCommander.call("echo", "After: onload");

         function doValidate() {
             var iban, valid;
             iban = $("#iban").val();
             valid = IBAN.isValid(iban);
             if (valid) {
                 $("#resultValid").show();
                 $("#resultInvalid").hide();
                 $("#validateButton").removeClass("invalid")
                                     .addClass("valid");
                 BridgeCommander.call("echo", `Validating: ${iban}, Result: valid`);
             } else {
                 $("#resultValid").hide();
                 $("#resultInvalid").show();
                 $("#validateButton").removeClass("valid")
                                     .addClass("invalid");
                 BridgeCommander.call("echo", `Validating: ${iban}, Result: invalid`);
             }

             setTimeout(function() {
                 $("#validateButton").removeClass("valid")
                                     .removeClass("invalid");
                 $("#resultValid").hide();
                 return $("#resultInvalid").hide();
             }, 3000);
             return false;
        };

         (function(doValidate) {
             BridgeCommander.call("echo", "Inside: onload");
             $("loader_overlay").css("display",'none');
             return $("#validateButton").on("click", doValidate);
         })(doValidate);

         window.document.getElementById("loader_overlay").innerHTML += ".";

         if (typeof window.appLoaded !== 'undefined') {
             window.document.getElementById("loader_overlay").innerHTML += ".";
         } else {
             window.document.getElementById("loader_overlay").innerHTML += "x";
         }
         if (window.module){ module = window.module; }
    });
});

On another note please get rid of all your file loading checks. 另一方面,请摆脱所有文件加载检查。 so all of the following code blocks 因此,以下所有代码块

if (typeof window.Handlebars !== 'undefined') {
    window.document.getElementById("loader_overlay").innerHTML += ".";
} else {
    window.document.getElementById("loader_overlay").innerHTML += "x";
}

They are only needed for debugging and you know it's Web Kit if the file loads on one it loads on all. 它们仅在调试时才需要,并且如果文件加载在一个文件上,那么它就是Web Kit。 so you don't need these check's they are just using phone processing power and adding work to your app for no good reason. 因此您不需要这些检查,因为它们只是在使用电话处理功能,并且没有充分的理由在您的应用程序中添加工作。 other than to put a . 除了放一个。 in the overlay... 在叠加层中...

and again all <script src=... should be inside the <head> tags, in this case, all of your code should be inside the script tags and using jQuery read as my above version does. 再次,所有<script src=...应该都位于<head>标记内,在这种情况下,您的所有代码都应该位于script标记内,并使用jQuery read读取上述版本。

How are you testing this App on the Mac are you using the iPhone emulator? 您如何在Mac上使用iPhone仿真器测试此应用程序? or a real iPhone to test i would always recommend the latter. 或真正的iPhone进行测试,我总是会推荐后者。 and have you tested in on one of these as you don't seem to say you have, if not get a device registered for testing on your developer account create the keys to test and build a test version then use Safari or chromes remote debugging tools on the WebView and make sure it all works. 并按照您似乎没有说过的方式对其中之一进行了测试,如果未在开发人员帐户上注册要测试的设备,请创建密钥以测试并构建测试版本,然后使用Safari或chromes远程调试工具在WebView上,并确保一切正常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM