JavaScript:原生JS实现Facebook实时消息抓捕
基础知识准备:
HTML5给我们提供了一个新的对象叫作:MutationObserver。为了兼容,还有WebKitMutationObserver、MozMutationObserver,挂靠在window下。
这个对象是干嘛的呢?
mutation:变化、变动、突变;
observer:观察者;
顾名思义,在DOM中,MutationObserver就是监听DOM变化的意思。
那么这个对象能够监听DOM的哪些变化呢?
- 子节点变化; ——–> childList
- 自身属性变化; ——–> attributes
- 自身的文本变化; ——–> characterData
以上三点呢是三大基本点。
至于这个对象怎么使用呢?很简单!
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
var observer = new MutationObserver(function(mutations) {});
- 1
- 2
- 3
上面的代码中,就是new了一个对象,里面传个callback回调函数而已,就这么简单,这个回调函数干嘛的?该回调函数会在指定的DOM节点(目标节点)发生变化时被调用. 该回调函数有一个参数mutations,这个参数是个数组,数组里每个元素是对象(包含了若干个MutationRecord对象的数组)。
该对象有几个方法要知道:
observe( Node target, optional MutationObserverInit options );
ovserve(要观察的目标节点, 你要观察目标节点的哪些东西-对象);
//举个例子,给你个人(目标节点),你想观察这个人的哪些指标变动:体重、身高、小孩等等
disconnect();//不再观察
好了,直接上个例子吧:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<divid="guoyu"></div>
<scripttype="text/javascript">var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver
// 选择目标节点var target = document.querySelector('#guoyu');
// 创建观察者对象,一旦目标节点发送变化,该回调立马执行var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
console.log(mutation.type);
});
console.log(mutations);//看看callback参数到底是什么
});
// 配置观察选项:你想观察目标节点哪些项var config = {
attributes: true,
childList: true,
characterData: true
}
// 传入目标节点和观察选项
observer.observe(target, config);
</script>
</body>
</html>
我们在id为”guoyu”的节点中添加一个节点,那么回调函数立马就会被触发执行:
看到了吧,我们在节点中插入一个子节点,立马触发了回调函数,并打印了我们想要的结果,而且改变的是childList。
再看一下,我这次把id给改了,看看有什么不同:
看到了吗,这次修改id属于属性的修改,打印出来的是attributes。
注: childList, attributes, 或者characterData三个属性中必须至少有一个为true.否则,会抛出异常”An invalid or illegal string was specified”.
下面呢,就着重介绍一下各个属性到底是啥意思!首先我们看看回调函数里的那个参数,这个参数上面说了是个数组,每个元素是个对象,具体名字参见上面截图。
我们在观察目标节点的时候,需要配置一个json对象,告诉浏览器我们要监听目标节点的哪些指标,比如:属性、子节点、文本、所有子孙节点等等。那么具体有哪些呢?
再举个例子吧,比如,我们既改变文本值,记录characterDataOldValue;又改变属性id的值,记录attributeOldValue。
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<divid="old_guoyu">I'am old</div>
<scripttype="text/javascript">var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver
var target = document.querySelector('#old_guoyu');
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
console.log(mutation.type);
});
console.log(mutations);
});
var config = {
attributes: true,
childList: true,
characterData: true,
characterDataOldValue: true,//监听老的文本值
attributeOldValue: true,//记录老的属性值
subtree: true
};
observer.observe(target, config);
</script>
</body>
</html>
看到没,此次我同时改变了文本值和属性值,回调函数执行了两次,一次是文本改变执行的,另一次是属性id改变执行的。说明MutationObserver准确的监听了所有的变化,并作出反应。
监听Facebook消息
有了上面的基础,我们就可以做很多有趣的东西。我们知道,每当有新的消息的时候,facebook会给你立即推送,但这是有前提的,你的软件必须和Facebook有合作,或者花钱买Facebook的服务消息推送。比如UC浏览器的海外版,UC浏览器就可以实时帮你推送Facebook的消息,因为UC和Facebook达成了合作,才会给你推送。
我们的突破口在Facebook首页的tab上,每当有新的消息,该主页上的tab会显示一个数字,只要我们实时监听到这个数字变化,就可以实时监听Facebook的消息,让你不用花钱也能实时获取消息提醒,这对于没有和Facebook达成合作协议的浏览器厂商十分有用。
前端可以使用原生JS实现对消息的实时监听,并把消息发送给浏览器客户端,浏览器客户端进行提醒,下面是一点跑除复杂业务需求的基本代码:
var MutationObserverMRN = window.MutationObserver || window.WebKitMutationObserver;
var observerM, targetM;
var observerR, targetR;
var observerN, targetN;
var configGYFBUI = {
'characterData' : true,
'characterDataOldValue' : true,
'childList': true,
'subtree' : true
};
functionobserverMessages(nodeId, type) {
var idDiv = document.getElementById(nodeId);
var parentM = (idDiv.childNodes[0].nodeName == 'A') ? idDiv.childNodes[0] : idDiv;
targetM = parentM.querySelectorAll('span')[1];
if (!observerM) {
observerM = new MutationObserverMRN(function(mutations) {
var strCount = (targetM.innerText == 'undefined') ? '0' : targetM.innerText;
if (parseInt(strCount) > 0) {
var url = 'https://m.facebook.com' + parentM.getAttribute('href');
var href = window.location.href;
var reg = /messages/;
if (!reg.test(href)) {
JSInterfaceManager.receiveFbNoti(type, url, strCount);
}
}
});
}
observerM.observe(targetM, configGYFBUI);
}
functionobserverRequests(nodeId, type) {
var idDiv = document.getElementById(nodeId);
var parentR = (idDiv.childNodes[0].nodeName == 'A') ? idDiv.childNodes[0] : idDiv;
targetR = parentR.querySelectorAll('span')[1];
if (!observerR) {
observerR = new MutationObserverMRN(function(mutations) {
var strCount = (targetR.innerText == 'undefined') ? '0' : targetR.innerText;
if (parseInt(strCount) > 0) {
var url = 'https://m.facebook.com' + parentR.getAttribute('href');
JSInterfaceManager.receiveFbNoti(type, url, strCount);
}
});
}
observerR.observe(targetR, configGYFBUI);
}
functionobserverNotifications(nodeId, type) {
var idDiv = document.getElementById(nodeId);
var parentN = (idDiv.childNodes[0].nodeName == 'A') ? idDiv.childNodes[0] : idDiv;
targetN = parentN.querySelectorAll('span')[1];
if (!observerN) {
observerN = new MutationObserverMRN(function(mutations) {
var strCount = (targetN.innerText == 'undefined') ? '0' : targetN.innerText;
if (parseInt(strCount) > 0) {
var url = 'https://m.facebook.com' + parentN.getAttribute('href');
JSInterfaceManager.receiveFbNoti(type, url, strCount);
}
});
}
observerN.observe(targetN, configGYFBUI);
}
observerMessages('messages_jewel', 'messages');
observerRequests('requests_jewel', 'requests');
observerNotifications('notifications_jewel', 'notifications');
JavaScript:原生JS实现Facebook实时消息抓捕的更多相关文章
- javascript原生js轮播图
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- [javascript]原生js实现Ajax
一.首先看JQuery提供的Ajax方法: $.ajax({ url: , type: '', dataType: '', data: { }, success: function(){ }, err ...
- JavaScript——原生js实现瀑布流
瀑布流介绍及实现原理: 瀑布流是一种页面布局,页面上也有多等宽的块(块就页面内容),每一块都是绝对定位(absolute),每个块排列的方式如下:寻找现在高度最小的列,把该块定位到该列下方.需要知道, ...
- javascript 原生js对html元素的 增删改查 操作
'use strict'; class View{ constructor(){ } //创建html元素 addEl(fel, elemName, id, cls){ //创建一个元素 let el ...
- 用原生JS实现AJAX和JSONP
前端开发在需要与后端进行数据交互时,为了方便快捷,都会选择JQuery中封装的AJAX方法,但是有些时候,我们只需要JQuery的AJAX请求方法,而其他的功能用到的很少,这显然是没必要的.其实,原生 ...
- vue实现实时监听文本框内容的变化(最后一种为原生js)
一.用watch方法监听这个变量. <!DOCTYPE html> <html> <head> <meta charset="utf-8" ...
- node.js中使用socket.io + express进行实时消息推送
socket.io是一个websocket库,包含客户端的js和服务端的node.js,可以在不同浏览器和移动设备上构建实时应用. 一.安装 socket.io npm install socket. ...
- 【javascript】原生js更改css样式的两种方式
下面我给大家介绍的是原生js更改CSS样式的两种方式: 1通过在javascript代码中的node.style.cssText="css表达式1:css表达式2:css表达式3 &quo ...
- 总结获取原生JS(javascript)的父节点、子节点、兄弟节点
关于原生JS获取节点,一直是个头疼的问题,而且调用方法的名字又贼长了,所以我选择用JQ,好像跑题了-- 话不多说看代码 获取父节点 及 父节点下所有子节点(兄弟节点) <ul> <l ...
随机推荐
- python-面向对象-13_文件
文件 目标 文件的概念 文件的基本操作 文件/文件夹的常用操作 文本文件的编码方式 01. 文件的概念 1.1 文件的概念和作用 计算机的 文件,就是存储在某种 长期储存设备 上的一段 数据 长期存储 ...
- (1.6)MySQL执行计划
关键词:mysql执行计划 1.用法 [1.1]explain select * from tab_name........ [1.2]desc select * from tab_name..... ...
- MongoDB与关系型数据库 区别
mysql mongodb 表 table Collection 字段 Colum Fields 行 row Document Mongo中的一些概念 ------------- ...
- python实现根据当前时间创建目录并输出日志
举个例子:比如我们要实现根据当前时间的年月日来新建目录来存放每天的日志,当前时间作为日志文件名称:代码如下: #!/usr/bin/env python3 # _*_ coding: utf-8 _* ...
- bcolz的新操作
1.直接修改 eg:把data.bcolz文件中A列为0的数据填充为1000. data = bcolz.open("data.bcolz", "a") #以& ...
- 万恶之源 - Python装饰器及内置函数
装饰器 听名字应该知道这是一个装饰的东西,我们今天就来讲解一下装饰器,有的铁子们应该听说,有的没有听说过.没有关系我告诉你们这是一个很神奇的东西 这个有多神奇呢? 我们先来复习一下闭包 def fun ...
- Dell R730服务器 Raid0 Raid5配置
Dell R730服务器,有7块5t硬盘,默认做的RAID5.我们的目的是取其中6块硬盘做RAID5,留一块硬盘做热备. 一块SSD系统盘. 在这里,我具体解释一下 ①6块硬盘做成RAID5 ②6块硬 ...
- zhaoyin
1.什么时候用到事务,单个update操作会用到事务吗? 银行转账 /**//*--使用事务--*/ use stuDB go --恢复原来的数据 --update bank set currentM ...
- vbox中安装mac系统
参考: https://www.cnblogs.com/liming2017/p/7566953.html
- 超参数调试、Batch正则化和编程框架
1.调试处理 2.为超参数选择合适的范围 3.超参数在实践中调整:熊猫与鱼子酱 4.正则化网络的激活函数 5.将batch norm拟合进神经网络 6. 为什么Batch Norm会起作用? 7.测试 ...