不影响所有手动点击,真正随心所欲;屏蔽后自动停止监听,不浪费一丝系统资源。
// ==UserScript== // @name 知乎屏蔽自动弹出登录框,不影响正常使用,比如手动点击登录,回答,关注,收藏等 // @namespace http://bbs.91wc.net/zhihu-no-modal.htm // @version 0.2.2 // @description 不影响所有手动点击,真正随心所欲;屏蔽后自动停止监听,不浪费一丝系统资源。 // @author Wilson // @icon https://static.zhihu.com/static/favicon.ico // @match *://www.zhihu.com/question/* // @license GPL License // ==/UserScript== (function() { 'use strict'; //是否开启调试模式 var debug = 0; //知乎弹窗有四种情况:1.不弹窗;2.仅加载时弹窗1次;3.加载和滚动时各弹窗1次;4.滚动条不在顶部时,加载时可能会加载2次弹窗 //日志输出 var def = function(v){return typeof v !== "undefined";} var log = function(v1,v2, v3){ if(!debug || !console||!console.log) return; if(def(v1) && def(v2) && def(v3)){console.log(v1,v2,v3);return;} if(def(v1) && def(v2)){console.log(v1,v2);return;} if(def(v1)){console.log(v1);return;} } //hideLogin标记是否手动点击登录 true代表系统自动弹出,false代表手动操作后的弹窗 var hideLogin = true, listenLoginRemoveFuns = []; //取消监听事件 var removeLoginModalEvent = function(evt){ listenLoginRemoveFuns[evt](); } //弹窗屏蔽处理函数 var listenLoginModal = function(evt){ log(evt, "监听开始"); //取消事件监听 var removeDOMNodeInsertedEvent = function(){ log(evt, "取消事件监听"); if(evt === "scroll"){ document.body.removeEventListener('DOMNodeInserted', scrollDOMNodeInsertedEvent, false); document.body.removeEventListener('click', scrollDOMClickEvent, false); }else{ document.body.removeEventListener('DOMNodeInserted', DOMNodeInsertedEvent, false); document.body.removeEventListener('click', DOMClickEvent, false); } if(removeLoadLoginTimer) clearTimeout(removeLoadLoginTimer); } listenLoginRemoveFuns[evt] = removeDOMNodeInsertedEvent; //处理弹窗屏蔽事件 var DOMNodeInsertedEvent = function(e){ if(!hideLogin || e.target.nodeType !== 1) return; var signFlowModal = e.target.getElementsByClassName('signFlowModal'); if(signFlowModal.length!==0){ //屏蔽系统自动弹出登录框 for(var i in signFlowModal){ if(signFlowModal[i] && signFlowModal[i].previousElementSibling){ log(evt, "屏蔽1次弹窗"); signFlowModal[i].previousElementSibling.click(); } } //屏蔽后,取消监听事件,以节省资源 if(removeLoadLoginTimer) clearTimeout(removeLoadLoginTimer); removeLoadLoginTimer=setTimeout(function(){ removeDOMNodeInsertedEvent(); }, 30000); } } if(evt === "scroll"){ //滚动时,再次监听弹窗事件 var scrollDOMNodeInsertedEvent = function(e){DOMNodeInsertedEvent(e);} document.body.addEventListener('DOMNodeInserted', scrollDOMNodeInsertedEvent, false); } else { //开始监听事件 document.body.addEventListener('DOMNodeInserted', DOMNodeInsertedEvent, false); } var removeLoadLoginTimer=0; if(evt === "load"){ //加载时,超过60秒内未弹窗,取消监听事件,以节省资源 removeLoadLoginTimer=setTimeout(function(){ removeDOMNodeInsertedEvent(); log(evt, '超时未弹窗');}, 60000); } //监听手动点击事件 var DOMClickEvent = function(){ log(evt, "触发点击事件"); hideLogin = false; setTimeout(function(){ hideLogin = true; }, 100); } if(evt === "scroll"){ var scrollDOMClickEvent = function(e){DOMClickEvent(e);} document.body.addEventListener('click', scrollDOMClickEvent, false); } else { document.body.addEventListener('click', DOMClickEvent, false); } } //监听刷新时的弹窗 listenLoginModal("load"); //监听滚动时的弹窗 var isListened = false; var DOMScrollEvent = function(){ if(!isListened){ isListened = true; removeLoginModalEvent("load"); listenLoginModal("scroll"); } log("scrollTop="+document.documentElement.scrollTop, "滚动监听中"); //滚动时,如果未加载弹窗则取消事件监听,这里知乎会在scrollTop1000-1500之间弹窗,这里保险起见取2000 var docEle = document.documentElement; if(docEle.scrollTop > 2000 || docEle.scrollTop+docEle.clientHeight === docEle.scrollHeight){ window.removeEventListener('scroll', DOMScrollEvent, false); log("scrollTop="+document.documentElement.scrollTop, "结束滚动事件"); setTimeout(function(){ removeLoginModalEvent("scroll"); }, 60000); } } window.addEventListener('scroll', DOMScrollEvent, false); })();