flutter-web中使用js工具类

简介: flutter-web中使用js工具类

为什么要调用js

JavaScript拥有庞大且成熟的工具生态系统

1. flutter-web

1. 引入js web/index.html
 <!-- Add the required JS libraries -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.2.0/crypto-js.min.js" integrity="sha512-a+SUDuwNzXDvz4XrIcXHuCf089/iJAoN4lmrXJg18XnduKK6YlDHNRalv4yd1N40OKI80tFidF+rqTFKGPoWFQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.2.0/md5.min.js" integrity="sha512-ENWhXy+lET8kWcArT6ijA6HpVEALRmvzYBayGL6oFWl96exmq8Fjgxe2K6TAblHLP75Sa/a1YjHpIZRt+9hGOQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

  <!-- Register the js file where the logic is written -->
  <script src="CryptoEnc.js" type="application/javascript"></script>
2. 创建工具js web/CryptoEnc.js
function CryptoEnc() {}

CryptoEnc.prototype.encrypt = function(toEncObj){
    var toEnc = toEncObj.value;

    var encrypted = CryptoJS.MD5(toEnc);

    return encrypted;
}


CryptoEnc.prototype.testFunc = function(toEncObj2){
  var toEnc = toEncObj2.value;
    return "========bbbbtestFunc"+toEnc;
}

3. 创建对应的lib/js/js_interop.dart
// #1
@JS()
library js_interop;

// The above two lines are required
import 'package:js/js.dart';

// #2
@JS()
class CryptoEnc {
  external CryptoEnc();

  external String encrypt(ToEncrypt toEncrypt);
  external String testFunc(ToEncrypt2 toEncrypt2);
}

// #3
@JS()
@anonymous
class ToEncrypt {
  external String get value;

  external factory ToEncrypt({String value});
}
@JS()
@anonymous
class ToEncrypt2 {
  external String get value;

  external factory ToEncrypt2({String value});
}


4. 由于引入的js是针对web平台的,所以引入需要做引入处理
///encrypt.dart
class ToEncrypt {
  final String value;

  ToEncrypt({
    required this.value,
  });
}

class ToEncrypt2 {
  final String value;

  ToEncrypt2({
    required this.value,
  });
}

class CryptoEnc {
  CryptoEnc();

  String encrypt(ToEncrypt toEncrypt) {
    // We are not implementing any encryption for mobile for now.
    // This is just for demonstration.
    throw UnimplementedError();
  }
  String testFunc(ToEncrypt2 toEncrypt) {
    // We are not implementing any encryption for mobile for now.
    // This is just for demonstration.
    throw UnimplementedError();
  }
}

///export_encrypt.dart
export 'encrypt.dart' if (dart.library.js) 'js_interop.dart';
5. 使用
   var encVal = CryptoEnc().encrypt(
      ToEncrypt(
        value: "aaaaaa",
      ),
    );
    var encVal2 = CryptoEnc().testFunc(ToEncrypt2(
      value: "cccc",
    ));
    print(encVal);
    print("testFunc=$encVal2");

2. Android

1. 引入依赖
webview_flutter: ^4.4.2
2. index.html
<!DOCTYPE html>
<html>
<head>
    <title>Test js dart</title>

</head>
<body>
<script>
   function inputClick (url) {
    console.log('inputClick=>'+url);
   }
   function playUrl(url) {
    console.log('playUrl=>'+url);
   }
   function startPlay() {
     console.log('startPlay');
   }
   function postMsg() {
     console.log('postMsg');
     //向dart发送消息
     Print.postMessage('postMsg');
   }

</script>
</body>
</html>
3. dart
import 'package:flutter/material.dart';
import 'package:tvboxstudy/log_extensions.dart';
import 'package:webview_flutter/webview_flutter.dart';

class LocalHtmlWebView extends StatefulWidget {
  const LocalHtmlWebView({super.key});

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

class LocalHtmlWebViewState extends State<LocalHtmlWebView> {
  late String localHtmlContents;
  late WebViewController controller;
  ValueNotifier<bool> isShowLoading = ValueNotifier(true);

  @override
  void initState() {
    super.initState();
    initController();
    loadLocalHtml();
    _registerJavascriptChannel();
  }

  void runJS(int type) {
    if (type == 1) {
      controller.runJavaScript(
        'inputClick();',
      );
    } else if (type == 2) {
      controller.runJavaScript(
        'startPlay();',
      );
    }else if (type == 3) {
      controller.runJavaScript(
        'postMsg();',
      );
    } else if (type == 4) {
      controller.runJavaScript(
        "playUrl('https://media.w3.org/2010/05/sintel/trailer.mp4');",
      );
    }
  }

  void _registerJavascriptChannel() {
    controller.addJavaScriptChannel(
      'Print',
      onMessageReceived: (JavaScriptMessage message) {
        //收到消息做相应的处理
        print("onMessageReceived=>${message.message}");
      },
    );
  }

  void initController() {
    controller = WebViewController()
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..setBackgroundColor(Colors.transparent)
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..setNavigationDelegate(
        NavigationDelegate(
          onProgress: (int progress) {
            "progress=$progress".log();
            if (progress == 100) {
              isShowLoading.value = false;
            }
          },
          onPageStarted: (String url) {},
          onPageFinished: (String url) {
            controller
                .runJavaScriptReturningResult('document.body.scrollHeight')
                .then((value) {
                  "scrollHeight=>$value".log();
            });
          },
          onWebResourceError: (WebResourceError error) {},
          onNavigationRequest: (NavigationRequest request) {
            if (request.url.startsWith('https://www.youtube.com/')) {
              return NavigationDecision.prevent;
            }
            return NavigationDecision.navigate;
          },
        ),
      );
  }

  void loadLocalHtml() async {
    controller.loadFlutterAsset('assets/www/player/index2.html');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          Row(
            children: [
              TextButton(onPressed: (){
                runJS(1);
              }, child: Text("inputClick")),
              TextButton(onPressed: (){
                runJS(2);
              }, child: Text("startPlay")),
              TextButton(onPressed: (){
                runJS(3);
              }, child: Text("postMsg")),
              TextButton(onPressed: (){
                runJS(4);
              }, child: Text("playUrl")),
            ],
          ),
          Expanded(
            child: Stack(
              children: [
                WebViewWidget(
                  controller: controller,
                ),
                ValueListenableBuilder(
                  valueListenable: isShowLoading,
                  builder: (BuildContext context, bool value, Widget? child) {
                    return isShowLoading.value
                        ? const Center(
                            child: CircularProgressIndicator(
                            color: Colors.white,
                          ))
                        : const SizedBox.shrink();
                  },
                )
              ],
            ),
          ),
        ],
      ),
    );
  }
}

相关文章
|
21天前
|
JavaScript 前端开发 安全
怎样用Node.js搭建web服务器
本文探讨了如何使用Node.js构建高效的HTTP服务器。首先,介绍了HTTP常见请求方法,如GET、POST、PUT等。接着,展示了如何使用Node.js的`http`模块创建服务器,并根据请求方法进行不同处理,如判断GET和POST请求,以及获取GET请求参数和处理POST请求数据。最后,讨论了服务器代码的模块化管理,包括路由管理和业务逻辑拆分,以提升代码的维护性和扩展性。通过本文,读者可以掌握基础的Node.js服务器开发及模块化设计技巧。
|
3天前
|
监控 JavaScript 前端开发
前端 JS 经典:Web 性能指标
前端 JS 经典:Web 性能指标
8 1
|
18天前
|
JavaScript 应用服务中间件 Apache
Node.js Web 模块
Node.js Web 模块
17 2
|
24天前
|
数据库 数据安全/隐私保护 Python
Web实战丨基于django+html+css+js的电子商务网站
Web实战丨基于django+html+css+js的电子商务网站
42 3
|
24天前
|
前端开发 安全 数据安全/隐私保护
Web实战丨基于django+html+css+js的在线博客网站
Web实战丨基于django+html+css+js的在线博客网站
29 2
|
8天前
|
缓存 JavaScript 前端开发
程序员必知:广告等第三方应用嵌入到web页面方案之使用js片段
程序员必知:广告等第三方应用嵌入到web页面方案之使用js片段
|
2月前
|
JavaScript Java 测试技术
基于springboot+vue.js的基于Web教师个人成果管理系统附带文章和源代码设计说明文档ppt
基于springboot+vue.js的基于Web教师个人成果管理系统附带文章和源代码设计说明文档ppt
30 7
|
2月前
|
JavaScript 前端开发
基于 Node.js 环境,使用内置 http 模块,创建 Web 服务程序
基于 Node.js 环境,使用内置 http 模块,创建 Web 服务程序
|
15天前
|
JavaScript 前端开发
杨校老师课堂之Web前端JS类库_JQuery案例[效果图与代码齐全]
杨校老师课堂之Web前端JS类库_JQuery案例[效果图与代码齐全]
16 0
|
23天前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp小程序的高校疫情防控web系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp小程序的高校疫情防控web系统附带文章源码部署视频讲解等
16 0