【问题标题】:Run some Javascript in Flutter Webview在 Flutter Webview 中运行一些 Javascript
【发布时间】:2018-10-25 06:36:53
【问题描述】:

如何在 flutter_webview_plugin 中运行 Javascript?我试过这个:

onPressed: () {
   flutterWebviewPlugin.evalJavascript('<script language="JavaScript" type="text/javascript">alert("Hello World")</script>');
},

但是什么也没发生。

我认为flutterWebviewPlugin.evalJavascript 可以在 Web 视图中运行 Javascript。 我是不是做错了什么?

【问题讨论】:

    标签: javascript webview dart flutter


    【解决方案1】:
    flutterWebviewPlugin.evalJavascript('<script language="JavaScript" type="text/javascript">alert("Hello World")</script>')
    

    需要 JavaScript,而不是 HTML

    <script language="JavaScript" type="text/javascript">alert("Hello World")</script>
    

    是 HTML。

    试试

    flutterWebviewPlugin.evalJavascript('alert("Hello World")')
    

    【讨论】:

    • 我试了一下,但什么也没发生。该网站在 WebviewScaffold 小部件中打开,其中包含带有 IconButton 的 appBar 可能是这里的错误?
    • 现在我在控制台中收到 SyntaxError。 I/chromium(14510): [INFO:CONSOLE(1)] "Uncaught SyntaxError: missing ) after argument list", 来源: (1)
    • 哦,抱歉,这是我的错。我的错。但它仍然不起作用。我直接从我的设备而不是模拟器尝试。
    • 好的,它适用于在控制台中打印或在文本字段中写入,但不适用于警报或 window.open。也许更多人不知道
    • @Günter 我可以运行这个:view.loadUrl("javascript:(function() { " + "var head = document.getElementsByClassName('header')[0].style.display='没有'; " +
    【解决方案2】:

    你可以试试我的插件flutter_inappwebview,这是一个 Flutter 插件,可以让你添加内联 WebViews 或打开应用内浏览器窗口,并且有很多事件、方法和选项来控制 WebViews。

    要运行一些js,可以使用:

    • Future&lt;dynamic&gt; evaluateJavascript({@required String source}):将 JavaScript 代码评估到 WebView 中并返回评估结果。
    • Future&lt;void&gt; injectJavascriptFileFromUrl({@required String urlFile}):将外部 JavaScript 文件从定义的 url 注入 WebView。
    • Future&lt;void&gt; injectJavascriptFileFromAsset({@required String assetFilePath}):将 JavaScript 文件从 Flutter assets 目录注入到 WebView(请参阅 here,了解如何从 assets 文件夹加载文件)。

    完整示例:

    import 'dart:async';
    
    import 'package:flutter/material.dart';
    
    import 'package:flutter_inappwebview/flutter_inappwebview.dart';
    
    Future main() async {
      runApp(new MyApp());
    }
    
    class MyApp extends StatefulWidget {
      @override
      _MyAppState createState() => new _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
    
      @override
      void initState() {
        super.initState();
      }
    
      @override
      void dispose() {
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
            home: InAppWebViewPage()
        );
      }
    }
    
    class InAppWebViewPage extends StatefulWidget {
      @override
      _InAppWebViewPageState createState() => new _InAppWebViewPageState();
    }
    
    class _InAppWebViewPageState extends State<InAppWebViewPage> {
      InAppWebViewController webView;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
                title: Text("InAppWebView")
            ),
            body: Container(
                child: Column(children: <Widget>[
                  Expanded(
                    child: Container(
                      child: InAppWebView(
                        initialUrl: "https://www.example.org/",
                        initialHeaders: {},
                        initialOptions: InAppWebViewWidgetOptions(
                          inAppWebViewOptions: InAppWebViewOptions(
                            debuggingEnabled: true,
                          ),
                        ),
                        onWebViewCreated: (InAppWebViewController controller) {
                          webView = controller;
                        },
                        onLoadStart: (InAppWebViewController controller, String url) {
    
                        },
                        onLoadStop: (InAppWebViewController controller, String url) async {
                          int result1 = await controller.evaluateJavascript(source: "10 + 20;");
                          print(result1); // 30
    
                          String result2 = await controller.evaluateJavascript(source: """
                            var firstname = "Foo";
                            var lastname = "Bar";
                            firstname + " " + lastname;
                          """);
                          print(result2); // Foo Bar
    
                          // inject javascript file from an url
                          await controller.injectJavascriptFileFromUrl(urlFile: "https://code.jquery.com/jquery-3.3.1.min.js");
                          // wait for jquery to be loaded
                          await Future.delayed(Duration(milliseconds: 1000));
                          String result3 = await controller.evaluateJavascript(source: "\$('body').html();");
                          print(result3); // prints the body html
    
                          // inject javascript file from assets folder
                          await controller.injectJavascriptFileFromAsset(assetFilePath: "assets/myJavascriptFile.js");
                        },
                      ),
                    ),
                  ),
                ]))
        );
      }
    }
    

    【讨论】:

    • 如何在这个插件中点击一个元素?如何检查用户是否按下了页面上的某个元素?
    • 嗨@Lorenzo Pichilli,我正在尝试将您的示例与Stripe一起使用。所以我的JS字符串用“ var stripe = Stripe(\'$pubStripeKey\'); stripe.redirectToCheckout({ sessionId: '${result['data']}' }).then(function (result) { result.error.message = '错误' }); ".但无论出于何种原因,我都无法对此进行评估。它在调用 await controller.evaluateJavascript() 时返回“null”。但也没有错误?有什么想法吗?
    • 可能是重定向的问题?但我尝试犯了一个错误,比如将 Stripe() 更改为 Stripey() 并且也没有看到错误。这就像我提供给 webview 的 JS 没有被评估。
    【解决方案3】:

    好吧,什么也没发生,因为 Flutter webview 不支持 javascript 警报功能。尝试编写一个 javascript 函数来更改 HTML 元素的 innerText 的值,然后使用 .evalJavascript 调用该函数以查看结果。

    【讨论】:

      【解决方案4】:

      我已经使用flutter_webview_plugin 的 iOS 部分进行了调试。

      iOS 部分

      发现与iOS原生部分iOS WKWebView not showing javascript alert() dialog 有关。

      很好的实现代码示例位于gist

      我为此创建了一个fix

      临时解决方案

      你可以使用

      flutter_webview_plugin:
          git:
            ref: "dev/fix_alert_not_work_in_webview"
            url: "https://github.com/jerryzhoujw/flutter_webview_plugin"
            source: git
      

      在合并 PR 之前将其作为 pubspec.yaml 中的临时值。

      【讨论】:

        【解决方案5】:

        这就是您的 Webview 小部件的外观

        WebView(
            initialUrl: 'http://<domain>',
            javascriptMode: JavascriptMode.unrestricted,
            onWebViewCreated: (WebViewController webViewController) {
              webViewController.evaluateJavascript(
                  'alert('hello from flutter)');
            }
        

        在代码中的任何位置使用webViewController

        【讨论】:

          猜你喜欢
          • 2019-10-08
          • 2013-12-10
          • 1970-01-01
          • 1970-01-01
          • 2011-12-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多