vue/uni-app h5 获取webview(iframe)的dom对象

注意:此文章方法仅适用于h5项目(同域名下,非同域名请使用跨域通讯达到目的)

        近期在一个一个新h5(uni-app)项目中需要使用webview(iframe)引用一个老项目,并对老项目的页面作出干涉以添加新功能因此需要获取到其dom对象来获取信息和操作页面

        

一、首先需要解决第一个问题,获取到本页面的iframe对象,这时候可能你会奇怪,本页面的iframe对象

//iframe.length - 1  这样写是因为我这个webview是一个公共组件
//有几个tabbar页面也引用了,会导致页面里会有好几个iframe
//经过我反复尝试当前显示的永远会在末尾
window.document.getElementsByTagName("iframe")[iframe.length - 1]

一下不就有了吗?确实是这样的,但是在uni-app项目里这却是一个大坑。

        1.在uniapp项目中,webview在渲染初期如下获取iframe标签对象的代码及其不稳定,成功获取到iframe标签的概率就像碰运气,这时候你会可能问为啥不等一会再获取呢?

太天真了,这里面的玄学你根本把握不住,

我因为需要实时获取应用页面状态所以在每次webview内部url地址变更后我都会循环操作40次,每0..5s一次,iframe标签就像鬼一样时有时无,太刺激了。所以这个项目前期功能异常不稳定,对引用页的操作失败率奇高。后来研究了很久,不知何时灵光一闪想到了一个很好的解决办法

let dom = window.document.getElementsByTagName("body")[0]
let iframe = dom.getElementsByTagName("iframe")
iframe = iframe[iframe.length - 1]

这样写iframe对象的获取成功率基本是加载完成就能获取到项目依仗这个办法运行异常平稳。

        2.最近有新功能加入,所以我又把项目拿出来改,改来改去发现了一个突然新增的问题,我都要疯了,这个问题有可能是我以前没发现也有可能是后续改动造成的影响。就是当你在某个webview页停留几分钟(或者在应用内,这个我没试,因为可以复现问题,尝试)那么

window.document.getElementsByTagName("body")

 方法会返回 undefined ,没错body竟然没有了,玄学吧。那您猜怎么着,这个时候我们最开始放弃的方法又可以非常准确的获取到iframe对象了,加倍的玄学,我说啊,写代码跟修仙似的,

所以最终把两者结合一下得到了一个非常稳定的获取webview dom对象的方法

let dom = window.document.getElementsByTagName("body")[0]
if(!dom){
    dom = window.document
}

let iframe = dom.getElementsByTagName("iframe")
iframe = iframe[iframe.length - 1]

try {
	if (iframe) {
		iframe = iframe.contentWindow
    }
}catch (e) {
	//TODO handle the exception
}

用这个新方法可以写一个监听webview地址变化的方法作为示例(我是懒得想其他办法,200毫秒虽然不算太快但是满足项目需求也就无所谓了)

checkWebHref() {
    let dom = window.document.getElementsByTagName("body")[0]
    if(!dom){
        dom = window.document
    }

    let iframe = dom.getElementsByTagName("iframe")
    iframe = iframe[iframe.length - 1]

    try {
	    if (iframe) {
		    iframe = iframe.contentWindow
			if (iframe.document && iframe.document.location && iframe.document.location.href){
                //获得ifram当前地址,至于监听,赋值给data对象使用watch监听就可以了
                console.log(iframe.document.location.href)
            }
        }
    }catch (e) {
	    //TODO handle the exception
    }
    
    //定时递归以达到监听目的
    setTimeout(() => {
		this.checkWebHref()
	}, 200)

}

各位大佬轻踩,笨人笨法,主要是解决问题

在此记录增加记忆

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值