好久没写博客了,业务一直在变化,陆陆续续的做了很多web app,被业务流淹没就很少有机会去反思,前端技术发展如此之快,常常有种不学则退的恐慌,一种技术还没吃透就涌出新的技术,然后一波人又打着各种旗帜去宣传,想偷懒都不行,大脑完全不够用。

Nodejs,AngularJS,vuejs,React,grunt,gulp,webpack...Fuck!

HTML5的水很深很深,感觉还有很多技术没有挖掘和使用。无意中发现HTML5 DOM4级MutatioObserver方法,可以检查页面中的DOM是否发生变化,说到这也许大家知道可以用来干嘛了。

确实,前段时间我们遇到了web app被运营商劫持的问题,不清楚哪个环节出了问题,换了https按理说应该不会再出现,后来想到用类似GA统计的方式去统计页面是否被注入了js脚本或者iframe,然后通过日志去查看异常问题。

劫持问题无非就是页面被修改了,DOM结构发生变化了被插入了小广告。看到MutatioObserver方法有种豁然开朗的感觉,虽然不能解决被劫持的问题,但是也能查看被注入了什么,也算涨了见识。

概述

MutationObserver从字面上含义就是发现突变。它可以监听页面的DOM元素是否发生了变化,然后给出通知。

Constructor

MutationObserver()

  1. new MutationObserver(callback)

callback,当每次DOM发生变化的时候都会触发callback,大家也许就会问,那要是频繁修改dom,那这个callback就会频繁触发,性能上怎么办?实际上,MutationObserver并不是每次dom发生变化的时候立即触发,还是等所有的dom操作完成之后一次执行,也就是说它是异步的。

举个栗子:

  1. <body>
  2. <ul id="container"></ul>
  3. </body>
  1. var callback=function(){
  2. console.log("Dom changed");
  3. };
  4. var mutationObserver=new MutationObserver(callback);
  5. var otpions={
  6. subtree:true,
  7. childList:true
  8. };
  9. mutationObserver.observe(document.body,otpions);
  10. window.onload=function(){
  11. for(var i=0;i<10;i++){
  12. var li=document.createElement("li");
  13. li.innerText="这是";
  14. document.getElementById("container").appendChild(li);
  15. }
  16. };

http://jsbin.com/nimilelote/edit?html,js,console,output

我们像DOM元素中插入了10次,实际上oberve只执行了一次,是在所有的dom操作完成之后触发的。

mutationObserver实例有三个方法。

observe(target,options)  //给制定的DOM注册一个事件,如果DOM发生变化就会发送通知。target是目标元素,比如body,options是配置哪写dom发生变化时才发送通知

disconnect();    //终止监听DOM变化,直到重新实例化

takeRecords()   //清除变动记录,即不再监听还没发生的DOM变化

observe实例化配置:

childList:设置为true表示监听指定元素的子元素的变动;

attributes:设置为true表示监听指定元素的属性的变动;

characterData:设置为true表示监听指定元素的data变动;

subtree:设置为true表示不紧监听目标元素也同时监听其子元素变动;

attributeOldValue:在attributes属性已经设为true的前提下,如果需要将发生变化的属性节点之前的属性值记录下来(记录到下面MutationRecord对象的oldValue属性中),则设置为true;

characterDataOldValue:在characterData属性已经设为true的前提下,如果需要将发生变化的characterData节点之前的文本内容记录下来(记录到下面MutationRecord对象的oldValue属性中),则设置为true.

attributeFilter:一个属性名数组(不需要指定命名空间),只有该数组中包含的属性名发生变化时才会被观察到,其他名称的属性发生变化后会被忽略.

  1. // Firefox和Chrome早期版本中带有前缀
  2. var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver
  3.  
  4. // 选择目标节点
  5. var target = document.querySelector('#some-id');
  6.  
  7. // 创建观察者对象
  8. var observer = new MutationObserver(function(mutations) {
  9. mutations.forEach(function(mutation) {
  10. console.log(mutation.type);
  11. });
  12. });
  13.  
  14. // 配置观察选项:
  15. var config = { attributes: true, childList: true, characterData: true }
  16.  
  17. // 传入目标节点和观察选项
  18. observer.observe(target, config);
  19.  
  20. // 随后,你还可以停止观察
  21. observer.disconnect();

HTML5 MutationObserver检测页面劫持的更多相关文章

  1. 通过HTML5 Visibility API检测页面活动状态

    几年前,我们浏览网页的时候是没有选项卡浏览模式的,每一个网页都会是一个浏览器窗口,如果我没有记错,Win7之前我们都是这样浏览网页的.作为一个程序员,我们经常会同时打开10-15个网页,多的时候超过2 ...

  2. HTML5中与页面显示相关的API

    1.HTML5中与页面显示相关的API 在HTML5中,增加了几个与页面显示相关的API,其中一个是Page Visibility API Page Visibility API  是指当页面变为最小 ...

  3. 关于html5与jsp页面同样的html代码展示的页面效果不一样的问题

    原文:关于html5与jsp页面同样的html代码展示的页面效果不一样的问题 html5默认的声明为 <!DOCTYPE html> jsp默认的声明头部为 <%@ page con ...

  4. HTML5 增强的页面元素

    一.HTML5 改良的 input 元素的种类 1.<input type="number" id="num1"> var n1 = documen ...

  5. 使用一个HttpModule拦截Http请求,来检测页面刷新(F5或正常的请求)

    在Web Application中,有个问题就是:“我怎么来判断一个http请求到底是通过按F5刷新的请求还是正常的提交请求?” 相信了解ASP.NET的人知道我在说什么,会有同感,而且这其实不是一个 ...

  6. HTML5+CSS3静态页面项目-PayPaul的总结

    学习前端有一段时间了,一直在看书上的理论知识,而实战项目却很少.师兄常说,想要知道自己的实力有多少,知识掌握了多少,最好的方法就是去实践了,实践出真知嘛.于是决定在这个假期里,主要是通过项目的实践以及 ...

  7. HTML5+CSS3静态页面项目-BusinessTheme的总结

    因为期末考试.调整心态等等的种种原因,距离上一次的项目练习已经过了很久了,今天终于有时间继续练习HTML5+CSS3的页面架构和设计稿还原.设计图很长,整个页面分为了好几个区域,所以就不放完整的设计图 ...

  8. html5实现本页面元素拖放和本地文件拖放

    HTML5拖放 拖放本地数据   1.HTML拖放 拖放(Drag 和 Drop)是HTML5标准的组成部分 2.拖放开始: ondragStart:调用了一个函数,drag(event),它规定了被 ...

  9. 超棒的HTML5/CSS3单页面响应式模板(支持Bootstrap)

    在线演示 使用Bootstrap实现的响应式单页面模板. 桌面效果: 移动设备效果: 阅读全文:超棒的HTML5/CSS3单页面响应式模板(支持Bootstrap)

随机推荐

  1. FunDA(15)- 示范:任务并行运算 - user task parallel execution

    FunDA的并行运算施用就是对用户自定义函数的并行运算.原理上就是把一个输入流截分成多个输入流并行地输入到一个自定义函数的多个运行实例.这些函数运行实例同时在各自不同的线程里同步运算直至耗尽所有输入. ...

  2. iOS完全自学手册——[二]Hello World工程

    1.前言 写第二篇文章之前,我在想第二篇应该怎么写?后来觉得与其写Objective-C语言的相关语法,不如直接开始写个小项目.语法简单入门即可.因为,即便把语法看的很深到最后还是不一定能做项目,运用 ...

  3. Redis查询&JDBC查询&Hibernate查询方式的效率比较...

    比较三种查询方式查询效率对比...我是用的JavaWeb的方式通过通过JSP页面查询的填写查询的参数...给予反馈.... 整个demo的下载地址:http://files.cnblogs.com/f ...

  4. Mime、base64编码

    第一部分 在阮一峰老师的博客中,是这样介绍Mime的: MIME的全称是"Multipurpose Internet Mail Extensions",中译为"多用途互联 ...

  5. Spring Security构建Rest服务-0102-Spring Social开发第三方登录之qq登录

    图一 基于SpringSocial实现qq登录,要走一个OAuth流程,拿到服务提供商qq返回的用户信息. 由上篇介绍的可知,用户信息被封装在了Connection里,所以最终要拿到Connectio ...

  6. Springboot+ajax传输json数组以及单条数据的方法

    Springboot+ajax传输json数组以及单条数据的方法 下面是用ajax传输到后台单条以及多条数据的解析的Demo: 结构图如下: 下面是相关的代码: pom.xml: <?xml v ...

  7. EF CodeFirst Mirgration

    新建类库Models,加入以下三个类: Product: public class Product { /// <summary> /// 编号 /// </summary> ...

  8. Ubuntu-16.04 R 安装及Jupyter notebook 配置

    1. R 安装 通常在Terminal下直接apt-get 即可,在16.10下可以get到R-3.3.1,目前最新好像是 R-3.4.2,可以去官方网站下载源码编译 (https://www.r-p ...

  9. BiLSTM+CRF 实体识别

    https://www.cnblogs.com/Determined22/p/7238342.html 这篇博客 里面这个公式表示抽象的含义,表示的是最后的分数由他们影响,不是直观意义上的相加. 为什 ...

  10. MySQL查询时区分大小写

    在创建MySQL数据库时,下面这些参数可供我们选择:*_bin: 表示的是binary case sensitive collation,也就是说是区分大小写的 *_cs: case sensitiv ...