当前位置: 首页 > news >正文

Flutter在web项目中使用iframe

需要把原来的app项目移植到web上面,在app中使用的是flutter_inappwebview这个库,推荐使用这个库,因为修复了一部分webview_flutter中存在的问题

在web项目中flutter_inappwebview这个库不支持,所以需要自己封装一个web项目中的webview也就是使用iframe

废话少说上代码

import 'dart:html';
import 'dart:js' as js;import 'dart:ui_web';import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:get/get.dart';
import 'package:myapp/app/services/screen_adapter.dart';Widget buildWebViewWidget(String url,{Function(int id)? onPlatformViewCreated}) {/// 给js调用的函数void back(){Get.back();}var platformViewRegistry = PlatformViewRegistry();//注册platformViewRegistry.registerViewFactory('iframe-webview', (_) {DivElement _mainDiv = DivElement()..style.width = '100%'..style.height = '100%'..style.position = 'relative';IFrameElement _iFameElement = IFrameElement()..style.height = '100%'..style.width = '100%'..src = url..style.border = 'none';ScriptElement scriptElement = ScriptElement();var script = """// 对话框jswindow.confirm = function(message, yesCallback, noCallback){var message = message;var choose = function(tag){return document.querySelector(tag);}choose('.dialog-message').innerHtml = message;choose(".wrap-dialog").className = "wrap-dialog";choose("#dialog").οnclick= function(e){if(e.target.className=="dialog-btn"){choose(".wrap-dialog").className = "wrap-dialog dialog-hide";yesCallback();}else if (e.target.className=="dialog-btn dialog-ml50"){choose(".wrap-dialog").className = "wrap-dialog dialog-hide";noCallback();}};}// 返回按钮功能var drag = document.getElementById("floatBtn");var gapWidth = ${ScreenAdapter.width(5)}var itemWidth = ${ScreenAdapter.width(80)}var itemHeight =  ${ScreenAdapter.width(80)}var clientWidth = document.documentElement.clientWidthvar clientHeight = document.documentElement.clientHeightvar newLeft = 0var newTop = 0drag.addEventListener('click',function(e){//e.stopPropagation();var r = confirm('确定返回首页吗?', function(){window.back();}, function(){})})drag.addEventListener('touchstart', function(e){// e.preventDefault();//e.stopPropagation();drag.style.transition = 'none';})drag.addEventListener('touchmove', function(e){// e.preventDefault();// e.stopPropagation();if (e.targetTouches.length === 1) {let touch = e.targetTouches[0]newLeft = touch.clientX - itemWidth / 2;newTop = touch.clientY - itemHeight / 2;if(newLeft  < 0){newLeft = 0} if(newLeft > clientWidth - itemWidth - gapWidth){newLeft > clientWidth - itemWidth - gapWidth}if(newTop < 0){newTop=0;}if(newTop > clientHeight - itemHeight - gapWidth){newTop = clientHeight - itemHeight - gapWidth}drag.style.left = newLeft + 'px'drag.style.top = newTop + 'px'}})drag.addEventListener('touchend', function (e) {// e.preventDefault()//e.stopPropagation();drag.style.transition = 'all 0.3s'if (newLeft > clientWidth / 2) {newLeft = clientWidth - itemWidth - gapWidth} else {newLeft = gapWidth}drag.style.left = newLeft + 'px'})   """;scriptElement.innerHtml = script;/// 返回按钮divDivElement _div = DivElement()..id = 'floatBtn'..draggable = true..style.width =  '${ScreenAdapter.width(80)}px'..style.height =  '${ScreenAdapter.width(80)}px'// ..style.backgroundColor = 'red'..style.backgroundImage = 'url(assets/assets/images/fanhui.png)'..style.backgroundSize = 'cover'..style.position = 'absolute'..style.left = '${ScreenAdapter.width(5)}px'..style.top = '0'..style.transition = 'all 0.3s'..style.zIndex = '9999';// 对话框样式StyleElement _style = StyleElement();_style.innerHtml = """html,body {margin: 0;padding: 0;font-family: "Microsoft YaHei";}.wrap-dialog {position: fixed;top: 0;left: 0;width: 100%;height: 100%;font-size: 16px;text-align: center;background-color: rgba(0, 0, 0, .4);z-index: 10000;display: flex;justify-content: center;align-items: center;}.dialog {position: relative;margin: 10% auto;width: 300px;background-color: #FFFFFF;}.dialog .dialog-header {height: 20px;padding: 10px;background-color: #22b9ff;}.dialog .dialog-body {height: 30px;padding: 20px;}.dialog .dialog-footer {padding: 8px;background-color: #f5f5f5;}.dialog-btn {width: 70px;padding: 2px;cursor: pointer;}.dialog-hide {display: none;}.dialog-ml50 {margin-left: 50px;}""";_mainDiv.append(_style);// 提示信息框domDivElement _dialogDiv = DivElement();_dialogDiv.innerHtml = """<div class="wrap-dialog dialog-hide" ><div class="dialog" id="dialog"><div class="dialog-header"><span class="dialog-title">提示</span></div><div class="dialog-body"><span class="dialog-message">确定要返回首页吗?</span></div><div class="dialog-footer"><input type="button" class="dialog-btn" id="dialog-confirm" value="确认" /><input type="button" class="dialog-btn dialog-ml50" id="dialog-cancel" value="取消" /></div></div></div>""";_mainDiv.append(scriptElement);_mainDiv.append(_dialogDiv);_mainDiv.append(_div);_mainDiv.append(_iFameElement);return _mainDiv;});/// 注册返回函数js.context['back'] = back;return SizedBox(width: double.infinity,height: double.infinity,child: HtmlElementView(viewType: 'iframe-webview',onPlatformViewCreated: (int id) {onPlatformViewCreated?.call(id);},),);
}

使用方法

直接判断是否是web,GetPlatform.isWeb ,如果是则使用上面封装的,不是则调用其他平台的

if(GetPlatform.isWeb)buildWebViewWidgetPlatform(controller.url,onPlatformViewCreated: (id) {controller.isLoading.value = false;})

参考网址

https://juejin.cn/post/7294638699417042954

相关文章:

Flutter在web项目中使用iframe

需要把原来的app项目移植到web上面&#xff0c;在app中使用的是flutter_inappwebview这个库&#xff0c;推荐使用这个库&#xff0c;因为修复了一部分webview_flutter中存在的问题 在web项目中flutter_inappwebview这个库不支持&#xff0c;所以需要自己封装一个web项目中的we…...

阿里云高校计划学生和教师完成认证领取优惠权益

阿里云高校计划学生和教师均可参与&#xff0c;完成学生认证和教师验证后学生可以免费领取300元无门槛代金券和3折优惠折扣&#xff0c;适用于云服务器等全量公共云产品&#xff0c;订单原价金额封顶5000元/年&#xff0c;阿里云百科aliyunbaike.com分享阿里云高校计划入口及学…...

劲松HPV防治诊疗中心提醒:做完HPV检查后,需留意这些事项!

在接受HPV检查后&#xff0c;有一些注意事项需要您注意。首先&#xff0c;要遵循医生的建议&#xff0c;并按照医生的指示进行后续治疗和随访。 其次&#xff0c;检查后可能会有些不适感&#xff0c;这是正常的现象&#xff0c;不必过于担心。但是&#xff0c;如果不适感持续加…...

InfoNCE Loss公式及源码理解

InfoNCE Loss公式及源码理解–从交叉熵损失谈起 当谈论到信息论中的损失函数时&#xff0c;InfoNCE&#xff08;Noise Contrastive Estimation&#xff09;和交叉熵损失都是两个关键的概念。它们不仅在衡量概率分布之间的差异方面发挥着重要作用&#xff0c;而且在深度学习的自…...

经典双指针算法试题(二)

&#x1f4d8;北尘_&#xff1a;个人主页 &#x1f30e;个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上&#xff0c;不忘来时的初心 文章目录 一、有效三角形的个数1、题目讲解2、讲解算法原理3、代码实现 二、查找总价格为目标值的两个商…...

MySQL -- DQL

1、select查询列和列名&#xff1a; --查询所有员工信息(*通配符&#xff0c;默认查询所有的列) select * from emp;--查询员工的姓名 select ename from emp;--查询员工的薪资 select sal from emp;--查询员工的姓名和薪资 select ename , sal from emp; select ename sal fr…...

高防CDN:保障网络安全的未来之路

在当前数字化飞速发展的时代&#xff0c;网络安全问题日益成为企业和个人关注的焦点。高防CDN&#xff08;Content Delivery Network&#xff0c;内容分发网络&#xff09;作为一种专注于防御网络攻击的解决方案&#xff0c;尽管在技术上表现卓越&#xff0c;但其普及却面临一系…...

使用wxPython和PyMuPDF合并PDF文档并自动复制到剪贴板

导语&#xff1a;处理大量的PDF文档可能会变得复杂和耗时。但是&#xff0c;使用Python编程和一些强大的库&#xff0c;如wxPython和PyMuPDF&#xff0c;可以使这个任务变得简单而高效。本文将详细解释一个示例代码&#xff0c;展示如何使用这些库来创建一个可以选择文件夹中的…...

Redis篇---第十四篇

系列文章目录 文章目录 系列文章目录前言一、为什么Redis的操作是原子性的,怎么保证原子性的?二、了解Redis的事务吗?四、Redis 的数据类型及使用场景前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男…...

python之文件操作

文件的读取、修改、写入 知识点&#xff1a;不可以使用for循环生成变量&#xff0c;替代方式&#xff1a;将每次循环生成的数据添加到列表中&#xff0c;再对列表进行操作 例子&#xff1a;根据输入的环境名称操作hosts文件&#xff0c;注释掉其他环境 #env1 127.0.0.1 127.0.…...

android实时投屏软件QtScrcpy

QtScrcpy 可以通过 USB / 网络连接Android设备&#xff0c;并进行显示和控制。无需root权限。 同时支持 GNU/Linux &#xff0c;Windows 和 MacOS 三大主流桌面平台。 QtScrcpy: Android实时投屏软件&#xff0c;此应用程序提供USB(或通过TCP/IP)连接的Android设备的显示和控制…...

LeetCode - 622. 设计循环队列(C语言,顺序存储结构,配图)

目录 ​编辑定义结构体&#xff1a; 1. MyCircularQueue(k): 构造器&#xff0c;设置队列长度为 k 2. Front: 从队首获取元素。如果队列为空&#xff0c;返回 -1 3. Rear: 获取队尾元素。如果队列为空&#xff0c;返回 -1 4. enQueue(value): 向循环队列插入一个元素。…...

在 Qt 框架中,有许多内置的信号可用于不同的类和对象\triggered

在 Qt 框架中&#xff0c;有许多内置的信号可用于不同的类和对象 以下是一些常见的内置信号的示例&#xff1a; clicked()&#xff1a;按钮&#xff08;QPushButton、QToolButton 等&#xff09;被点击时触发的信号。 pressed() 和 released()&#xff1a;按钮被按下和释放时…...

springBoot中starter

springBoot项目中引入starter 项目引入xxljob&#xff0c;仅需要导入对应的starter包&#xff0c;即可进行快速开发 <dependency><groupId>com.ydl</groupId><artifactId>xxl-job-spring-boot-starter</artifactId><version>0.0.1-SNAPS…...

Linux学习笔记-Ubuntu下使用Crontab设置定时任务

文章目录 一、概述二、基于crontab的设置2.1 基本命令说明2.2 使用-e指令编辑命令2.2.1 进入编辑模式2.2.2 指令信息格式2.2.4 开启日志1) 修改rsyslog配置文件2) 重启rsyslog3) 查看日志 2.2.3 设置后之后重启服务 三、示例3.1 每隔一分钟往文件中日期3.2 使用-l查看任务列表3…...

动态规划求数组中相邻两数的最小差值( 即相差的绝对值 ) java 实现

算法的核心是&#xff1a;计算当前数和前一个数的差值,用该差值和以前最小的连续数的差值作比较&#xff1b;如果当前的差值更小&#xff0c;则发现了更小的连续数的差值&#xff1b;如果当前的差值更大&#xff0c;则沿用以前的最小连续数差值作为新的最小连续数差值。 MinDif…...

webGL开发微信小游戏

WebGL 是一种用于在浏览器中渲染 2D 和 3D 图形的 JavaScript API。微信小游戏本质上是在微信环境中运行的基于 Web 技术的应用&#xff0c;因此你可以使用 WebGL 来开发小游戏。以下是基于 WebGL 开发微信小游戏的一般步骤&#xff0c;希望对大家有所帮助。北京木奇移动技术有…...

leetcode面试经典150题——29 三数之和

题目&#xff1a;盛最多水的容器 描述&#xff1a; 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且不重复的三元组。 注意…...

数据分析基础之《jupyter notebook工具》

一、安装库 1、linux库 yum install python3-devel 2、python库 pip3 install -U matplotlib pip3 install -U numpy pip3 install -U pandas pip3 install -U TA-Lib pip3 install -U tables pip3 install -U notebook 3、如果TA-Lib安装不上&#xff0c;先手动安装依赖库 …...

Android Studio Error “Unsupported class file major version 61“---异常信息记录

编译时异常信息 原因及解决办法 问题出在JAVA 17上&#xff0c;并且使用的Gradle JDK是&#xff1a;Android Studio java home版本17.0.1将其更改为&#xff1a;Android Studio默认JDK版本11.0.10 即可解决 操作步骤 1 2 3...

vscode里如何用git

打开vs终端执行如下&#xff1a; 1 初始化 Git 仓库&#xff08;如果尚未初始化&#xff09; git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...

C++初阶-list的底层

目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

Java 8 Stream API 入门到实践详解

一、告别 for 循环&#xff01; 传统痛点&#xff1a; Java 8 之前&#xff0c;集合操作离不开冗长的 for 循环和匿名类。例如&#xff0c;过滤列表中的偶数&#xff1a; List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

vulnyx Blogger writeup

信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面&#xff0c;gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress&#xff0c;说明目标所使用的cms是wordpress&#xff0c;访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...

LRU 缓存机制详解与实现(Java版) + 力扣解决

&#x1f4cc; LRU 缓存机制详解与实现&#xff08;Java版&#xff09; 一、&#x1f4d6; 问题背景 在日常开发中&#xff0c;我们经常会使用 缓存&#xff08;Cache&#xff09; 来提升性能。但由于内存有限&#xff0c;缓存不可能无限增长&#xff0c;于是需要策略决定&am…...

CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!

本文介绍了一种名为AnomalyAny的创新框架&#xff0c;该方法利用Stable Diffusion的强大生成能力&#xff0c;仅需单个正常样本和文本描述&#xff0c;即可生成逼真且多样化的异常样本&#xff0c;有效解决了视觉异常检测中异常样本稀缺的难题&#xff0c;为工业质检、医疗影像…...

Elastic 获得 AWS 教育 ISV 合作伙伴资质,进一步增强教育解决方案产品组合

作者&#xff1a;来自 Elastic Udayasimha Theepireddy (Uday), Brian Bergholm, Marianna Jonsdottir 通过搜索 AI 和云创新推动教育领域的数字化转型。 我们非常高兴地宣布&#xff0c;Elastic 已获得 AWS 教育 ISV 合作伙伴资质。这一重要认证表明&#xff0c;Elastic 作为 …...

Ubuntu系统多网卡多相机IP设置方法

目录 1、硬件情况 2、如何设置网卡和相机IP 2.1 万兆网卡连接交换机&#xff0c;交换机再连相机 2.1.1 网卡设置 2.1.2 相机设置 2.3 万兆网卡直连相机 1、硬件情况 2个网卡n个相机 电脑系统信息&#xff0c;系统版本&#xff1a;Ubuntu22.04.5 LTS&#xff1b;内核版本…...