有时候还是用油猴方便,WebDriver考虑的太多
//获取元素,一直查询,直到找到为止,参数名称比较好理解 function getElement(parent, selector, timeout = 0) { return new Promise(resolve => { let result = parent.querySelector(selector); if (result) return resolve(result); let timer; const mutationObserver = window.MutationObserver || window.WebkitMutationObserver || window.MozMutationObserver; if (mutationObserver) { const observer = new mutationObserver(mutations => { for (let mutation of mutations) { for (let addedNode of mutation.addedNodes) { if (addedNode instanceof Element) { result = addedNode.matches(selector) ? addedNode : addedNode.querySelector(selector); if (result) { observer.disconnect(); timer && clearTimeout(timer); return resolve(result); } } } } }); observer.observe(parent, { childList: true, subtree: true }); if (timeout > 0) { timer = setTimeout(() => { observer.disconnect(); return resolve(null); }, timeout); } } else { const listener = e => { if (e.target instanceof Element) { result = e.target.matches(selector) ? e.target : e.target.querySelector(selector); if (result) { parent.removeEventListener('DOMNodeInserted', listener, true); timer && clearTimeout(timer); return resolve(result); } } }; parent.addEventListener('DOMNodeInserted', listener, true); if (timeout > 0) { timer = setTimeout(() => { parent.removeEventListener('DOMNodeInserted', listener, true); return resolve(null); }, timeout); } } }); }
//劫持XHR,懂得都懂 function addXMLRequestCallback(callback){ //是一个劫持的函数 var oldSend, i; if( XMLHttpRequest.callbacks ) { //判断XMLHttpRequest对象下是否存在回调列表,存在就push一个回调的函数 // we've already overridden send() so just add the callback XMLHttpRequest.callbacks.push( callback ); } else { // create a callback queue XMLHttpRequest.callbacks = [callback]; //如果不存在则在xmlhttprequest函数下创建一个回调列表 // store the native send() oldSend = XMLHttpRequest.prototype.send; //获取旧xml的send函数,并对其进行劫持 // override the native send() XMLHttpRequest.prototype.send = function(){ // process the callback queue // the xhr instance is passed into each callback but seems pretty useless // you can't tell what its destination is or call abort() without an error // so only really good for logging that a request has happened // I could be wrong, I hope so... // EDIT: I suppose you could override the onreadystatechange handler though for( i = 0; i < XMLHttpRequest.callbacks.length; i++ ) { XMLHttpRequest.callbacks[i]( this ); } //循环回调xml内的回调函数 // call the native send() oldSend.apply(this, arguments); //由于我们获取了send函数的引用,并且复写了send函数,这样我们在调用原send的函数的时候,需要对其传入引用,而arguments是传入的参数 } } } //使用范例 /* addXMLRequestCallback( function( xhr ) { //调用劫持函数,填入一个function的回调函数 //回调函数监听了对xhr调用了监听load状态,并且在触发的时候再次调用一个function,进行一些数据的劫持以及修改 xhr.addEventListener("load", function(){ if ( xhr.readyState == 4 && xhr.status == 200 ) { //console.log( xhr.responseURL ); //your code //console.log(xhr.responseText); } }); }); */