简体   繁体   English

在 Flutter Webview 中运行一些 Javascript

[英]Run some Javascript in Flutter Webview

How can I run Javascript in flutter_webview_plugin?如何在 flutter_webview_plugin 中运行 Javascript? I tried with this:我试过这个:

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

But nothing happens.但什么也没有发生。

I thought with flutterWebviewPlugin.evalJavascript it's possible to run Javascript in a Webview.我认为使用flutterWebviewPlugin.evalJavascript可以在 Webview 中运行 Javascript。 Did I do something wrong?我做错什么了吗?

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

expects JavaScript, not HTML需要 JavaScript,而不是 HTML

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

is HTML.是 HTML。

Try尝试

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

You can try my plugin flutter_inappwebview , which is a Flutter plugin that allows you to add inline WebViews or open an in-app browser window and has a lot of events, methods, and options to control WebViews.你可以试试我的插件flutter_inappwebview ,这是一个 Flutter 插件,它允许你添加内联 WebView 或打开应用内浏览器窗口,并且有很多事件、方法和选项来控制 WebView。

To run some js, you can use:要运行一些 js,您可以使用:

  • Future<dynamic> evaluateJavascript({@required String source}) : Evaluates JavaScript code into the WebView and returns the result of the evaluation. Future<dynamic> evaluateJavascript({@required String source}) :将 JavaScript 代码计算到 WebView 中并返回计算结果。
  • Future<void> injectJavascriptFileFromUrl({@required String urlFile}) : Injects an external JavaScript file into the WebView from a defined url. Future<void> injectJavascriptFileFromUrl({@required String urlFile}) :从定义的 url 将外部 JavaScript 文件注入 WebView。
  • Future<void> injectJavascriptFileFromAsset({@required String assetFilePath}) : Injects a JavaScript file into the WebView from the flutter assets directory (see more here on how to load a file from the assets folder). Future<void> injectJavascriptFileFromAsset({@required String assetFilePath}) :将 JavaScript 文件从 flutter 资产目录注入 WebView(有关如何从资产文件夹加载文件的更多信息,请参见此处)。

Full example:完整示例:

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");
                    },
                  ),
                ),
              ),
            ]))
    );
  }
}

Well, nothing happened because flutter webview does not support javascript alert function.好吧,什么也没发生,因为 flutter webview 不支持 javascript 警报功能。 Try writing a javascript function that changes the value of the innerText of an HTML element and then call the function using .evalJavascript to see the result.尝试编写一个 javascript 函数来更改 HTML 元素的 innerText 的值,然后使用 .evalJavascript 调用该函数以查看结果。

I have debug with iOS part of flutter_webview_plugin .我已经调试了flutter_webview_plugin iOS 部分。

For iOS part对于 iOS 部分

Found it's related to iOS native part iOS WKWebView not showing javascript alert() dialog .发现它与 iOS 本地部分iOS WKWebView not shows javascript alert() dialog 相关

Good example of implement code are at gist .实现代码的好例子是gist

I have create a fix for this.我已经为此创建了一个修复程序

Temp solution临时解决方案

You can use您可以使用

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

this as temp in pubspec.yaml before merge PR .这在合并PR之前作为pubspec.yaml temp 。

This is how your Webview widget should look like这就是您的 Webview 小部件的外观

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

Make use of webViewController anywhere in your code在代码中的任何地方使用webViewController

My best way with onPressed function using the webview_flutter .我使用 webview_flutter 使用onPressed function的最佳方式。 Use ' runJavascript ' or evaluateJavascript or ' runJavascriptReturningResult ':使用“ runJavascript ”或评估Javascript 或“ runJavascriptReturningResult ”:

import 'package:flutter/material.dart';
import 'dart:io';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:flutter/services.dart';


dynamic ctrl; // Created here to keep working with Hot Reload

void main() {
  runApp(
    MaterialApp(
      home: WebViewExample(),
    ),
  );
}

class WebViewExample extends StatefulWidget {
  @override
  WebViewExampleState createState() => WebViewExampleState();
}

class WebViewExampleState extends State<WebViewExample> {
  @override
  void initState() {

    super.initState();

    // Enable virtual display.
    if (Platform.isAndroid) WebView.platform = AndroidWebView();

  }


  @override
  Widget build(BuildContext context) {

    void runJS(command) async {
      ctrl.runJavascript(command);

      // If you get any result
      // dynamic r = await ctrl.runJavascriptReturningResult(command);
      // print(r);
    }

    return Scaffold(
      appBar: AppBar(
          title: Container(
        child: ElevatedButton(
          onPressed: () => {
            runJS('alert("Hello: Button Clicked! "+new Date())')
          },
          child: const Text('Click on the button'),
        ),
      )),
      body: WebView(
        initialUrl:
            'https://www.google.com',

        debuggingEnabled: true,

        onWebViewCreated: (WebViewController webViewController) {
         
          ctrl = webViewController;
         
          ctrl.runJavascript('alert("Hello: created!")');
          // ctrl.evaluateJavascript('alert("Hello: created!")');
          // ctrl.runJavascriptReturningResult('alert("Hello: created!")');
        },

        onPageStarted: (String url) async {
          // ctrl.runJavascript('alert("Hello: started!")');
          // ctrl.evaluateJavascript('alert("Hello: started!")');
          // ctrl.runJavascriptReturningResult('alert("Hello: started!")');
        },

        onPageFinished: (String url) async {
          // ctrl.runJavascript('alert("Hello: finished!")');
          // ctrl.evaluateJavascript('alert("Hello: finished!")');
          // ctrl.runJavascriptReturningResult('alert("Hello: finished!")');
        },
      ),
    );
  }
}

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

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