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

App使用webview套壳引入h5(三)——解决打包为app后在安卓机可物理返回但是在苹果手机无法测滑返回的问题

话不多说,直接放最终版本代码。

解决思路是:如果设备是ios设备在myH5中监听 touchstart 和touchend事件

经过 App使用webview套壳引入h5的最终代码如下
myApp中,entry.vue代码如下:

<template><view class="entry-page" :style="{ paddingTop: safeAreaInsets.top + 'px' }"><web-view :webview-styles="webviewStyles" :src="webviewUrl" @message="getH5Message" ref="webViewRef"></web-view></view>
</template><script>
export default {data() {return {statusBarHeight: 100,safeAreaInsets: {},webviewUrl: 'myLink', hasBottomSafeArea: false,webviewStyles: {progress: {color: '#007aff',top: 0},// iOS侧滑返回配置ios: {allowsBackForwardNavigationGestures: true, // 启用WKWebView侧滑手势bounces: false // 禁用弹性效果}},webview: '',isIOS: false,          // 判断是否为iOS设备webviewCanBack: false  // WebView是否可返回};},onReady() {var currentWebview = this.$scope.$getAppWebview().children()[0];this.webview = currentWebview; // 缓存WebView实例currentWebview.addEventListener('loaded', () => {			currentWebview.evalJS('$("ul.fed-part-rows a[href*=\'resource.i847.cn\']").parent().hide();');});},onLoad(options) {// #ifdef APP-PLUSthis.isIOS = uni.getSystemInfoSync().platform === 'ios'; // 检测iOS设备let _this = this;let height = 0;let statusbar = 0;const sysInfo = uni.getSystemInfoSync();this.safeAreaInsets = sysInfo.safeAreaInsets;console.log('top--------', sysInfo);this.statusBarHeight = sysInfo.statusBarHeight;height = sysInfo.windowHeight;let currentWebview = this.$scope.$getAppWebview();setTimeout(() => {var wv = currentWebview.children()[0];console.log('top--------222222222', _this.statusBarHeight);wv.setStyle({top: _this.statusBarHeight,height: height - _this.statusBarHeight,scalable: false});}, 200);// #endif},onBackPress(e) {// 响应返回事件(关键修改,此处测试发行仅在打包为安卓的情况下可响应onBackPress)if (this.isIOS) {// iOS设备:优先WebView内部返回if (this.webviewCanBack) {this.webview.back(); // WebView返回上一级H5页面return true; // 拦截默认返回}}// 其他情况执行原有逻辑this.webView = this.$mp.page.$getAppWebview().children()[0];this.webView.evalJS('window.getPageUrl()');return true;},methods: {test() {console.log('test webview');},dealBackEvent() {console.log('dealBackEvent webview');},showCurrentPage(pageInfo) {console.log('showCurrentPage', pageInfo);if (pageInfo.pathname) {const targetArray = ['pages/index/index', 'tab页2', 'tab页3'];const processedString = pageInfo.pathname.replace('myLink地址中的页面公共路径', '');const exists = targetArray.includes(processedString);if (exists) {console.log('showCurrentPage ----------1');uni.showModal({title: '提示',content: '确定要退出吗?',success: (res) => {if (res.confirm) {plus.runtime.quit();}}});} else {console.log('showCurrentPage ----------2');// 优先WebView返回(关键修改)if (this.webviewCanBack) {this.webview.back();} else {this.webView.back();}}}},getH5Message(e) {console.log('来自webview的消息*******************', e);var item = e.detail.data[0];switch (item.type) {case 'back':this.operation();break;case 'outApp':this.back();break;case 'isFun':this[item.action](item.message);break;case 'historyChange':// 接收H5历史变化通知(关键修改)this.webviewCanBack = item.data.canBack;break;case 'iosBack':// 接收iOS返回通知(关键修改)if (!item.data.canBack) {uni.navigateBack();}break;default:uni.showToast({title: item.message,duration: 2000});break;}},operation() {// #ifdef APP-PLUSthis.webView = this.$mp.page.$getAppWebview().children()[0];console.log('operation********', this.webView);// #endif},back() {uni.showModal({title: '提示',content: '是否退出系统?',success: function (res) {if (res.confirm) {plus.runtime.quit();} else if (res.cancel) {console.log('用户点击取消');}}});}}
};
</script><style>
.entry-page {background-color: #f8f8f8;
}.webview-container {flex: 1;width: 100%;
}
</style>

myH5项目中
记得引入webviewJs,参考 App使用webview套壳引入h5(一)
App.vue的代码如下

<script>export default {data() {return {isIos: false,transitionName: '', // 过渡动画的名称startPosition: {x: 0,y: 0}, // 手势开始时的位置};},created() {console.log("at app created---0", this.startPosition);// 初始化数据this.startPosition = {x: 0,y: 0};this.isIOS = uni.getSystemInfoSync().platform === 'ios'; // 检测iOS设备console.log("at app created---1", this.startPosition,this.isIOS);},mounted() {console.log("at app mounted---0", this.startPosition);let that = this// 使用$nextTick确保DOM和数据完全初始化后执行this.$nextTick(() => {console.log("at app mounted---1", that.startPosition);console.log("at app mounted---2", that.startPosition.x);// 初始化事件监听that.initEventListeners();});},methods: {// 将事件监听逻辑提取为单独的方法initEventListeners() {if (this.isIOS) {// 监听touchstart事件window.addEventListener('touchstart', (event) => {this.handleTouchStart(event);});// 监听touchend事件window.addEventListener('touchend', (event) => {this.handleTouchEnd(event);});}// 确保uni对象存在后执行初始化this.initUniAppBridge();},// 处理touchstart事件handleTouchStart(event) {this.startPosition.x = event.touches[0].pageX;this.startPosition.y = event.touches[0].pageY;},// 处理touchend事件handleTouchEnd(event) {const endPosition = {x: event.changedTouches[0].pageX,y: event.changedTouches[0].pageY,};// 计算手势滑动的距离const deltaX = endPosition.x - this.startPosition.x;const deltaY = endPosition.y - this.startPosition.y;console.log("touchend---------2");// 判断滑动方向与滑动距离是否符合返回操作的条件if (Math.abs(deltaX) > Math.abs(deltaY) && Math.abs(deltaX) > 30) {if (deltaX > 0) {// 获取当前路由栈的长度const pages = getCurrentPages();const stackLength = pages.length;console.log('[H5] popstate触发,历史长度:', window.history.length, this.$router, stackLength);// 向右滑动,执行返回上一页的操作this.transitionName = 'slide-right';// this.$router.go(-1);uni.navigateBack()}// else if (deltaX < 0) {//         // 向左滑动,执行前进一页的操作//         this.transitionName = 'slide-left';//         this.$router.go(1);//       }}},// 初始化与uni-app的桥接initUniAppBridge() {// 和webview进行网页通信document.addEventListener('UniAppJSBridgeReady', () => {uni.webView.getEnv((res) => {console.log('当前环境:' + JSON.stringify(res));});uni.webView.postMessage({data: {message: '我是来自H5的消息',action: 'test',type: 'isFun'}});});window.getPageUrl = (arg) => {uni.webView.postMessage({data: {action: 'showCurrentPage',message: location,type: 'isFun',}});};},},beforeDestroy() {if (this.isIos) {// 移除所有事件监听window.removeEventListener('touchstart', this.handleTouchStart);window.removeEventListener('touchend', this.handleTouchEnd);}}}
</script><style lang="scss">
</style>

相关文章:

  • Uniapp 二维码生成与解析完整教程
  • win32相关(远程线程和远程线程注入)
  • Spring框架学习day7--SpringWeb学习(概念与搭建配置)
  • 深度解析地质灾害风险普查:RS与GIS技术在泥石流、滑坡灾害中的应用,ArcGIS数据管理、空间数据转换、专题地图制作、DEM分析及实战案例分析
  • 实用对比图软件推荐:快速呈现信息差异
  • opencv-4.8.1到 sln
  • Excel数据分析:基础
  • Tensorrt python api 10.11.0笔记
  • 红花UGT鉴定与特征分析-文献精读142
  • 本地部署大模型实战:使用AIStarter一键安装Ollama+OpenWeb教程(含最新版本更新指南)
  • 适用于vue3的大屏数据展示组件库DataV(踩坑版)
  • QQ邮箱发送验证码(Springboot)
  • vue和uniapp聊天页面右侧滚动条自动到底部
  • 第六个微信小程序:教师工具集
  • 负载均衡将https请求转发后端http服务报错:The plain HTTP request was sent to HTTPS port
  • [Zynq] Zynq Linux 环境下 AXI UART Lite 使用方法详解(代码示例)
  • opencv如何在仿射变换后保留完整图像内容并自动裁剪
  • OpenCV 图像通道的分离与合并
  • elementUI点击浏览table所选行数据查看文档
  • 解决el-select选择框右侧下拉箭头遮挡文字问题
  • 邢台手机网站建设费用/百度网盘app
  • 展览公司设计费/安徽seo人员
  • 做网站市场大不大/免费做网站
  • 网站建设可以自学吗/外链工具在线
  • jsp网站源码 怎么用/白山网络推广
  • 昆山做网站的公司/免费发帖的平台有哪些