2

通过 FlutterWebviewPlugin 的实现,我想在一个小部件中显示一个特定的网站,但没有页眉和页脚。这在 Flutter 中可行吗?我猜 FlutterWebviewPlugin 类中有一个函数 .evalJavascript('some code') 但不知道如何使用这个函数。我可以在其中添加 javascript 代码吗?

import 'package:flutter/material.dart';
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';

String url = "https://flutter.io/";

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Webview Example',
      theme: ThemeData.dark(),
      routes: {
        "/": (_) => Home(),
        "/webview": (_) => WebviewScaffold(
          url: url,
          withJavascript: true,
          withLocalStorage: true,
          withZoom: true,
        )
      },
    );
  }
}

class Home extends StatefulWidget {
  @override
  HomeState createState() => HomeState();
}

class HomeState extends State<Home> {
  final webView = FlutterWebviewPlugin();
  TextEditingController controller = TextEditingController(text: url);

  @override
  void initState() {
    super.initState();
    webView.close();
    controller.addListener(() {
      url = controller.text;
    });
  }
  @override
  void dispose() {
    webView.dispose();
    controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("WebView"),
        ),
        body: Center(
          child: Column(
            children: <Widget>[
              Container(
                padding: EdgeInsets.all(10.0),
                child: TextField(
                  controller: controller,
                ),
              ),
              RaisedButton(
                child: Text("Open Webview"),
                onPressed: () {

                  Navigator.of(context).pushNamed("/webview");
                },
              )
            ],
          ),
        )
    );
  }
}
4

2 回答 2

2

我建议使用 Flutter 的官方 WebView 插件:webview_flutter

该插件还有一个方法可以使用WebViewController.evaluateJavascript(String). 该方法建议在WebView.onPageFinished回调后运行。

您的 WebView 小部件应如下所示。

WebView(
    initialUrl: 'https://flutter.dev',
    javascriptMode: JavascriptMode.unrestricted,
    onWebViewCreated: (WebViewController webViewController) {
      _webViewController = webViewController;
      _controller.complete(webViewController);
    },
    onProgress: (int progress) {
      print("WebView is loading (progress : $progress%)");
    },
    onPageStarted: (String url) {
      print('Page started loading: $url');
    },
    onPageFinished: (String url) {
      print('Page finished loading: $url');

      // Removes header and footer from page
      _webViewController
          .evaluateJavascript("javascript:(function() { " +
              "var head = document.getElementsByTagName('header')[0];" +
              "head.parentNode.removeChild(head);" +
              "var footer = document.getElementsByTagName('footer')[0];" +
              "footer.parentNode.removeChild(footer);" +
              "})()")
          .then((value) => debugPrint('Page finished loading Javascript'))
          .catchError((onError) => debugPrint('$onError'));
      },
);

这是您可以尝试的完整示例。

import 'dart:async';

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final Completer<WebViewController> _controller =
      Completer<WebViewController>();

  WebViewController _webViewController;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Builder(builder: (BuildContext context) {
        return WebView(
          initialUrl: 'https://flutter.dev',
          javascriptMode: JavascriptMode.unrestricted,
          onWebViewCreated: (WebViewController webViewController) {
            _webViewController = webViewController;
            _controller.complete(webViewController);
          },
          onProgress: (int progress) {
            print("WebView is loading (progress : $progress%)");
          },
          javascriptChannels: <JavascriptChannel>{
            _toasterJavascriptChannel(context),
          },
          navigationDelegate: (NavigationRequest request) {
            if (request.url.startsWith('https://www.youtube.com/')) {
              print('blocking navigation to $request}');
              return NavigationDecision.prevent;
            }
            print('allowing navigation to $request');
            return NavigationDecision.navigate;
          },
          onPageStarted: (String url) {
            print('Page started loading: $url');
          },
          onPageFinished: (String url) {
            print('Page finished loading: $url');

            _webViewController
                .evaluateJavascript("javascript:(function() { " +
                    "var head = document.getElementsByTagName('header')[0];" +
                    "head.parentNode.removeChild(head);" +
                    "var footer = document.getElementsByTagName('footer')[0];" +
                    "footer.parentNode.removeChild(footer);" +
                    "})()")
                .then((value) => debugPrint('Page finished loading Javascript'))
                .catchError((onError) => debugPrint('$onError'));
          },
          gestureNavigationEnabled: true,
        );
      }),
    );
  }

  JavascriptChannel _toasterJavascriptChannel(BuildContext context) {
    return JavascriptChannel(
        name: 'Toaster',
        onMessageReceived: (JavascriptMessage message) {
          // ignore: deprecated_member_use
          Scaffold.of(context).showSnackBar(
            SnackBar(content: Text(message.message)),
          );
        });
  }
}

应用程序看起来如何运行

演示

于 2021-03-17T21:49:04.970 回答
1
_webViewController.runJavascript(
          "document.getElementsByTagName('header')[0].style.display='none'");
      _webViewController.runJavascript(
          "document.getElementsByTagName('footer')[0].style.display='none'");
于 2021-12-12T13:12:03.160 回答