JS MutationObserver 简单应用场景

MutationObserver

 

记录项目中用到MutationObserver的一个场景。

应用场景:

  1. App中用WebView显示一个本地html文件
  2. html文件下载JavaScript然后用JSONP显示一个网页
  3. 这个网页中实际内容是用iframe显示的一个表单
  4. 表单中有一个Close按钮
  5. 需求就是点击Close按钮的时候关掉App中引入WebView的页面

简单来说就是想捕捉iframe里面的Close按钮的点击事件。

因为捕捉到了点击事件就可以把这个事件传入到App层,App就可以关闭页面。

 

尝试解决以及遇到的问题:

最开始我尝试用jQuery为close按钮加上click的点击事件的监听。

代码如下:

 $('.cancel').click(function() {
          window.postMessage('close', '*')
        }) 

一般情况(*下面会稍稍尝试解释下一般情况是什么情况*)下这么做是没问题的,但对我来说不能用。我先说为什么我不能用这个方法。

我项目中html的结构是这样:

* 本地HTML

** 一个container div

** container div里面有一个iframe 显示了具体表单内容 (JSONP运行之后的结果)

这样以来,我访问container div没问题,因为这些div是被JSONP直接追加到我本地的HTML的DOM中的

有问题的是,我访问不了container div里面的iframe的内容,因为iframe的src是一个远程服务器上的页面,比如 当你在本地一个html文件里面写上:

<iframe id="baidu" src="http://www.baidu.com" height="800" width="800">
</iframe>

在你的HTML文件里你是访问不到这个iframe里面的内容的。

我们知道访问一个iframe的document对象是这样操作:

var document = IFRAME.contentDocument || IFRAME.contentWindow.contentDocument

但当我访问contentDocument对象的时候我遇到了这个:

frame.contentWindow.contentDocument
VM107:1 Uncaught DOMException: Blocked a frame with origin "null" from accessing a cross-origin frame.
    at <anonymous>:1:21

刚开始很不解,我都已经加载了这个页面了 我为什么不能修改他的内容?

后来我想可能是这样,如果可以任意修改iframe里面的内容的话 我可以把Baidu的logo改成任意其他的图片,然后供其他人访问这个页面,这样看起来太不合适了 可能这就是上面提出的 “cross-origin" 即跨域调用的安全性问题。

* 什么是“一般情况”?如果要显示的html文件不是在本地而是在服务器上,比如百度做一个新版首页,而新版首页想要直接加载这个页面那肯定是没问题的,因为他们不是跨域调用。

用MutationObserver解决:

因为点击Close按钮会把iframe从页面中移除,所以,用MutationObserver解决非常合适。

代码简单,如下:

        var target = document.querySelector('#container')

        var observer = new MutationObserver(function(mutations) { // 设定监听回调函数
          if (!$('#container').children().length) {
            window.postMessage('close', '*')
            console.log('Iframe was closed')
          }
        });
        observer.observe(target, {
          childList: true,
        })

这样以来,我们对container进行监听,我们设定了监听他的childList,即当他的子节点有变动的时候 会触发我们设定的监听回调函数。在这个函数中我们去看container的子节点数量,如果变为0了说明Close按钮被点击过了。当然,点击Submit按钮也会移除iframe,那么这个回调也会被执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值