使用H5新增MutationObserver,监听iframe的Url变化。

本文介绍如何使用MutationObserver接口来监听iframe的URL变化,并提供了一个简单的示例代码,展示了如何配置观察器并实现对URL变动的响应。

MutationObserver接口提供了监视对DOM树所做更改的能力,通俗点来说就是用来监视 DOM 变动,比如增加删除, 浏览器窗口大小改变导致挤压DOM,属性的变动(width,height,src,style)文本内容的变动等等。

这里我只用来监听iframe的url变化,来进行操作

代码:

    var target = document.getElementById("mainFrame"); // 目标节点iframe
    var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver
    // 创建一个观察器实例
    var observer = new MutationObserver(items => {
        items.forEach(item =>{
            console.log(item)
            iframeChange(item.oldValue, item.target.src, item.target)
        })
    })
    // 观察器的配置
    var options = {
        childList: false,// 子节点的变动(指新增,删除或者更改) Boolean
        attributes: true, // 属性的变动      Boolean
        subtree: false, //表示是否将该观察器应用于该节点的所有后代节点      Boolean
        attributeOldValue: true, // 表示观察attributes变动时,是否需要记录变动前的属性 Boolean  
        characterData: false, // 节点内容或节点文本的变动 Boolean
        attributeFilter: ["src"] // 表示需要观察的特定属性 Array,如['class','src', 'style']
    }
    // 开始观察目标节点
    observer.observe(target, options);
    function iframeChange(oldValue, newValue, iframeData){
        //console.log("旧地址:"+oldValue)
        //console.log("新地址:"+newValue)
        if(newValue == oldValye){
            window.location.href = ......
            // or othorCode ....
        }
    }

打印 item;

有兴趣的小伙伴试试看吧~

<template> <!-- 整体容器 --> <view class="evidence-detail-container"> <!-- 新增顶部导航栏 --> <view class="custom-navbar"> <!-- 返回按钮 --> <view class="back-btn" @click="handleBack"> <text class="back-icon">←</text> <text class="back-text">返回</text> </view> <!-- 标题 --> <view class="navbar-title">证据详情</view> <view class="back-btn" @click="shareEvidence"> <text class="back-icon">-></text> <text class="back-text">分享</text> </view> <view class="navbar-right"></view> </view> <view class="certificate-title"> 可信时间戳认证证书 </view> <!-- PDF 预览区域 --> <view class="pdf-preview-container"> <web-view v-if="pdfUrl && !loading" :src="`/static/pdf-preview.html?pdfUrl=${encodeURIComponent(pdfUrl)}`" ></web-view> </view> </view> </template> <script> export default { data() { return { evidenceInfo: {}, // 证据信息 pdfUrl: '', // 预览URL loading: true, error: '', evidenceId: null, // 证据ID byteArray: null ,// 字节数组 }; }, onLoad(options) { console.log('接收参数:', options); this.evidenceId = options.evidenceId; // 加载证据信息 this.loadEvidenceInfo(); }, methods: { handleBack() { uni.navigateBack({ delta: 1 }); }, // 加载证据详情 loadEvidenceInfo() { const evidenceList = uni.getStorageSync('evidenceList') || []; this.evidenceInfo = evidenceList.find(item => item.id === parseInt(this.evidenceId)) || {}; if (!this.evidenceInfo.base64Data) { this.error = '未找到证据数据'; this.loading = false; return; } // 转换Base64为字节数组并生成预览URL this.convertBase64ToByteArray(this.evidenceInfo.base64Data); }, // Base64转字节数组(Uint8Array) convertBase64ToByteArray(base64Data) { try { // 1. Base64解码为二进制字符串 const binaryString = atob(base64Data); // 2. 转换为字节数组 this.byteArray = new Uint8Array(binaryString.length); for (let i = 0; i < binaryString.length; i++) { this.byteArray[i] = binaryString.charCodeAt(i); } console.log('字节数组转换成功:', this.byteArray); // 3. 生成可预览的Blob URL this.generatePdfUrlFromByteArray(); } catch (e) { console.error('字节数组转换失败:', e); this.error = '证据数据解析失败'; this.loading = false; } }, // 从字节数组生成PDF预览URL generatePdfUrlFromByteArray() { try { // 小程序/APP环境:使用本地路径 if (this.evidenceInfo.pdfUrl && this.evidenceInfo.pdfUrl.includes('wxfile://') || this.evidenceInfo.pdfUrl.includes('file://')) { this.pdfUrl = this.evidenceInfo.pdfUrl; this.loading = false; } else { // H5环境:生成Blob URL const blob = new Blob([this.byteArray], { type: 'application/pdf' }); this.pdfUrl = URL.createObjectURL(blob); this.loading = false; } } catch (e) { console.error('生成PDF URL失败:', e); this.error = 'PDF加载失败'; this.loading = false; } }, // 导出PDF exportPdf() { if (!this.byteArray) { uni.showToast({ title: '无证据数据可导出', icon: 'none' }); return; } uni.showLoading({ title: '导出中...' }); // 根据环境处理导出 if (typeof uni.saveFile === 'function' && this.evidenceInfo.pdfUrl) { // 小程序/APP:使用本地路径 uni.saveFile({ tempFilePath: this.evidenceInfo.pdfUrl, success: (res) => { uni.hideLoading(); uni.showModal({ title: '导出成功', content: `已保存至: ${res.savedFilePath}`, showCancel: false }); }, fail: (err) => { uni.hideLoading(); console.error('保存失败:', err); uni.showToast({ title: '导出失败', icon: 'none' }); } }); } else { // H5:通过a标签下载 const blob = new Blob([this.byteArray], { type: 'application/pdf' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = this.evidenceInfo.fileName || 'evidence.pdf'; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); uni.hideLoading(); uni.showToast({ title: '导出成功', icon: 'none' }); } }, shareEvidence() { uni.showToast({ title: '分享功能待实现', icon: 'none' }); } } }; </script> <style scoped> /* 整体容器样式 */ .evidence-detail-container { width: 100%; min-height: 100vh; background-color: #f5f5f5; position: relative; padding-top: 80rpx; /* 留出导航栏高度 */ box-sizing: border-box; /* 确保padding不影响整体宽度 */ } /* 新增的顶部导航栏样式 */ .custom-navbar { position: fixed; /* 固定在顶部 */ top: 0; left: 0; display: flex; justify-content: space-between; align-items: center; height: 80rpx; background-color: #2e8bff; padding: 0 20rpx; z-index: 999; width: 100%; } .back-btn { display: flex; align-items: center; color: #fff; } .back-icon { font-size: 20px; margin-right: 5px; } .back-text { font-size: 16px; } .pdf-view { width: 30%; /* 宽度30% */ height: 100rpx; /* 高度100rpx */ margin: 80rpx auto 0; /* 距离顶部80rpx,水平居中 */ border: 1px solid #ddd; /* 增加边框便于识别 */ } .navbar-title { color: #ffffff; font-size: 36rpx; font-weight: bold; flex: 1; text-align: center; } .navbar-right { width: 44px; /* 占位,可根据实际功能调整 */ } .certificate-title { text-align: center; height: 120rpx; /* 增大高度,避免文字被截断 */ line-height: 120rpx; /* 与高度一致,确保垂直居中 */ font-size: 36rpx !important; /* 强制设置字体大小,增加优先级 */ font-weight: bold !important; color: #333 !important; margin: 30rpx 0 !important; /* 增加上下间距 */ /* 增加背景色便于观察区域范围 */ background-color: transparent; /* 确保没有其他样式干扰 */ padding: 0; border: none; } .pdf-preview-container { width: 100%; /* 宽度占满父容器 */ height: 70vh; /* 高度为视窗高度的70% */ margin-top: 20rpx; /* 与上方元素的间距 */ border: 1px solid #eee; /* 可选边框 */ border-radius: 8rpx; /* 圆角 */ overflow: hidden; /* 隐藏内部溢出内容 */ box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.1); /* 阴影效果 */ } /* 适配不同平台 */ /* 在H5环境中,web-view渲染为iframe */ /* #ifdef H5 */ .pdf-preview-container iframe { width: 40%; height: 30%; border: none; } </style> 怎样改变webview宽度 和高度 内容自适应
最新发布
08-20
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值