// ==UserScript==
// @name check the links is visible or not
// @author burningall
// @description 检查超链接是否有效
// @version 2015.8.21
// @include *
// @grant GM_registerMenuCommand
// @grant GM_xmlhttpRequest
// @run-at document-start
// @compatible chrome 推荐
// @compatible firefox 不推荐
// @license The MIT License (MIT); http://opensource.org/licenses/MIT
// @supportURL http://www.burningall.com
// @contributionURL [email protected]|alipay.com
// @namespace https://gf.qytechs.cn/zh-CN/users/3400-axetroy
// ==/UserScript==
(function(document){
var config = {
"autoLoad":false//脚本开始加载,是否自动ajax。(不建议为true,大量ajax会影响性能,甚至假死)
};
function Ob(target,config,fn){
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
var observer = new MutationObserver(function(mutations){
mutations.forEach(function(mutation) {
fn.call(target);
});
});
observer.observe(target, config);
}
function addEvent(obj, type, fn){
return obj.addEventListener ?
obj.addEventListener(type, function(e){
var ev = window.event ? window.event : (e ? e : null);
if( fn.call(obj,ev)===false ){
e.cancelBubble = true;//阻止冒泡
e.preventDefault();//chrome,firefox下阻止默认事件
}
}, false)
:
obj.attachEvent('on' + type, function(e){
ev.target = ev.target || ev.srcElement;
if(fn.call(obj,ev)===false ){
e.cancelBubble = true;//阻止冒泡
return false;//阻止默认事件,针对IE8
}
});
}
function check(urlLink,a,secFn,failFn){
a.setAttribute("checking",true);
GM_xmlhttpRequest({
method: "GET",
url: urlLink,
onerror: function(response ){
failFn(a);
},
onreadystatechange:function(response){
if(response.readyState==4){
var status = response.status+'';
if( status.charAt(0)=="4" || status.charAt(0)=="5" ){//4XX,5XX错误
failFn(a);
}else{
secFn(a);
}
}
}
});
}
var reg = /[a-zA-z]+:\/\/[^\s]*/i;
function init(){
var link = document.querySelectorAll('a[href*="http"]:not([checking]):not([visible])');
var arr = [];
var temps = [];
var agms = 20;
if( link.length>=200 && link.length<500 ){
agms = 50;
}else if(link.length>=500){
return;
}
var step = Math.ceil( (link.length-1)/agms );//分组,总共agms组装完,每组step个数
for(var j=0;j<link.length;j++){
//每隔10个
if( j>0 && j%step===0 ){
arr.push( temps );
temps = [];
}
//收尾零头
if( link.length-j<step ){
temps.push( link[j] );
if( link.length-1==j ){
arr.push( temps );
temps = [];
}
}else{
temps.push( link[j] );
}
}
// console.log( link.length + ":" +arr.length );
var num = 0;
function start(index){
if( arr.length<1 || typeof arr[index] == "string" || typeof (arr[index]) !== "object" ){
return;
}
//判断这一组是否加载完毕
var jugg = [];
for(var y=0;y<arr[index].length;y++){
var a = arr[index][y];
if( reg.test(a.href)===false || a.getAttribute('visible')!==null ){
continue;
}
check(a.href,a,function(a){
//成功
// a.style.cssText = "background:rgba(46, 212, 169, 0.14) !important";
if( a.getAttribute('visible')==="false" ){
a.style.cssText = "background:rgba(46, 212, 169, 0.14) !important; text-decoration:none !important;color:#ccc !important";
}
a.setAttribute('visible',"true");
a.removeAttribute('checking');
jugg.push(true);
if(num>arr.length-1){
return;
}
if(jugg.length>=length-1){
setTimeout(function(){
start(num++);
},200);
}
},function(){
//失败
a.style.cssText = "background:red !important; text-decoration:line-through !important;color:#ccc !important";
a.setAttribute('visible',"false");
a.removeAttribute('checking');
jugg.push(false);
if(num>arr.length-1){
return;
}
if(jugg.length>=length-1){
setTimeout(function(){
start(num++);
},200);
}
});
console.log( index+":"+y );
}
}
start(num);
}
addEvent(document,'mouseover',function(e){
var target = e.target || e.srcElement;
if( target.tagName == "A" && reg.test(target.href) ){
if( target.getAttribute('visible')==="true" ){
return;
}
check(target.href,target,function(target){
//加载成功
if( target.getAttribute('visible')==="false" ){
target.style.cssText = "background:rgba(46, 212, 169, 0.14) !important; text-decoration:none !important;color:#ccc !important";
}
target.setAttribute('visible',"true");
target.removeAttribute('checking');
},function(){
//加载失败
target.style.cssText = "background:red !important; text-decoration:line-through !important;color:#ccc !important";
target.setAttribute('visible',"false");
target.removeAttribute('checking');
});
}
});
addEvent(window,'DOMContentLoaded',function(){
if( config.autoLoad === true ){
init();
new Ob(document.documentElement,{
"childList":true,
"subtree":true
},function(){
init();
});
}
});
//注册(不可用)菜单
GM_registerMenuCommand("检查全部链接", init);
})(document);