// ==UserScript== // @name 知乎浏览助手 // @namespace http://tampermonkey.net/ // @version 0.0.4 // @description 知乎浏览助手. 如果想报 bug, 可以通过知乎私信联系我, zhihu.com/people/kougazhang // @author kgzhang // @match https://www.zhihu.com/* // @grant GM_addStyle // @grant GM_log // @downloadURL none // ==/UserScript== // 问题页加宽 GM_addStyle(".Question-mainColumn { width: unset !important; } "); GM_addStyle(".QuestionAnswers-answers { width: 1000px !important; } "); // 推荐页加宽 GM_addStyle(".Topstory-mainColumn { width: 1000px !important; } "); // 去除右边栏 GM_addStyle(".GlobalSideBar { display: none !important; } "); // 去除问题页右边栏 GM_addStyle(".Question-sideColumn { display: none !important; } "); // 去除 topic 右边栏 GM_addStyle(".ContentLayout-sideColumn { display: none !important; } "); // topic 加宽 GM_addStyle(".Topic-bar--borderBottom {width: 1000px;}"); // 搜索页加宽 GM_addStyle(".ListShortcut {width: 1000px; font-size: 20px}"); // 搜索页隐藏右边栏 SearchSideBar GM_addStyle(".SearchSideBar {display: none;}"); // 个人页面隐藏右边栏 GM_addStyle(".Profile-sideColumn {display: none; }"); // 加宽 GM_addStyle(".Profile-mainColumn {width: 1000px; }"); (function () { 'use strict'; // Your code here... const urlZhiHuFeed = "https://www.zhihu.com/"; const reUrlZhiHuQuestion = /https:\/\/www.zhihu.com\/question\/.*/; const reUrlZhiHuFollow = /https:\/\/www.zhihu.com\/follow.*/; const color = [ {name: 'blue', value: '#0084ff'}, {name: 'green', value: '#5cb85c'}, {name: 'red', value: '#d9534f'}, {name: 'green2', value: '#004E00'}, {name: 'gray', value: 'gray'}, ]; const btnStyle = 'margin-top: 15px; margin-bottom: 15px; margin-left:-18px; cursor:pointer; color: #fff; border-radius: 3px; border: 1px solid; padding: 3px 6px'; const getColor = (name) => { for (let c of color) { if (c.name === name) { return c.value; } } }; // 复制剪贴板 function updateClipboard(newClip) { navigator.clipboard.writeText(newClip).then(function () { alert('succeed copy'); }, function (err) { // clipboard write failed console.info('failed copy', err); alert('faild copy') }); } // 防抖 function debounce(fn, wait) { let timeout = null; return function () { if (timeout !== null) clearTimeout(timeout); timeout = setTimeout(fn, wait); } } class ElementEventSwitch { constructor(conf) { this.true = '1'; this.false = '0'; this.$all = { do: { status: this.true, color: conf.do.color, confirmInfo: conf.do.confirmInfo, eleText: conf.do.eleText, action: () => { if (confirm(this.$all.do.confirmInfo)) { this.mountEvent(); this.setLocalStatus(this.$all.do.status); this.changeColor(this.$all.do.color); this.changeInnerText(this.$all.do.eleText); } } }, undo: { status: this.false, color: conf.undo.color, eleText: conf.undo.eleText, confirmInfo: conf.undo.confirmInfo, action: () => { if (confirm(this.$all.undo.confirmInfo)) { this.unmountEvent(); this.setLocalStatus(this.$all.undo.status); this.changeColor(this.$all.undo.color); this.changeInnerText(this.$all.undo.eleText); } } } }; this.eleID = conf.eleID; this.eleType = conf.eleType; this.eleStyle = conf.eleStyle; this.text = conf.eleText; this.eventType = conf.eventType; this.eventAction = conf.eventAction; } create() { // 根据 localStatus 进行初始化动作 let color = this.$all.do.color; let text = this.$all.do.eleText; if (this.localStatusIsTrue()) { this.mountEvent(); } else { color = this.$all.undo.color; text = this.$all.undo.eleText; } // 创建元素 const ele = createEle(this.eleType, text, { id: this.eleID, style: `background: ${color}; ${this.eleStyle}` }); ele.addEventListener('click', (e) => { !this.localStatusIsTrue() ? this.$all.do.action() : this.$all.undo.action(); }); return ele; } localStatusIsTrue() { return localStorage.getItem(this.eleID) === this.$all.do.status } setLocalStatus(status) { localStorage.setItem(this.eleID, status); } mountEvent() { window.addEventListener(this.eventType, this.eventAction); } unmountEvent() { window.removeEventListener(this.eventType, this.eventAction); } changeColor(color) { document.getElementById(this.eleID).style.backgroundColor = color; } changeInnerText(text) { document.getElementById(this.eleID).innerText = text; } } // 创建元素 function createEle(eleName, text, attrs) { let ele = document.createElement(eleName); ele.innerText = text; for (let k in attrs) { ele.setAttribute(k, attrs[k]); } return ele; } function block(item) { const move = (x) => { x.style.display = "none"; }; if (item === undefined) { return undefined; } else if (item instanceof window.NodeList) { item.forEach(i => block(i)); } else { move(item); } } // 屏蔽非问题推荐 function displayQuestionOnly() { // 只在 feed 页生效 if (location.href !== urlZhiHuFeed) { return; } for (let item of document.getElementsByClassName('TopstoryItem-isRecommend')) { const title = item.getElementsByTagName('a')[0].innerText; if (!title.endsWith("?")) { block(item); } else { } } } // 屏蔽热榜 function blockTopStoryHot() { block(document.querySelectorAll('a[href="/hot"]')); } function blockActivity() { block(document.querySelector('a[class="css-w3ttmg"]')); } // 过滤推荐 function addBtnDisplayQuestion() { const conf = { do: { confirmInfo: '确认开启过滤推荐?', color: getColor('blue'), eleText: '过滤:)', }, undo: { color: getColor('gray'), confirmInfo: '确认关闭过滤推荐?', eleText: '过滤:(' }, eleStyle: btnStyle, eleID: 'btnElementEventSwitch', eleType: 'a', eventType: 'scroll', eventAction: debounce(displayQuestionOnly, 100), }; const btnQuestion = new ElementEventSwitch(conf); // 显示在热榜节点的后面 const eleRecommend = document.querySelectorAll('a[href="/"]')[1]; eleRecommend.parentElement.insertBefore(btnQuestion.create(), eleRecommend.nextSibling); } function addReprintBtn() { let num = 0; for (let item of document.querySelectorAll('div[class="List-item"]')) { const eleMeta = item.getElementsByClassName('ContentItem-meta')[0]; const answerID = item.getElementsByTagName('div')[0].getAttribute('name'); if (document.getElementById(answerID)) { continue; } const text = eleMeta.parentElement.getElementsByClassName("RichContent")[0].innerText; const reprintBtn = createEle('button', '一键转载', { id: answerID, style: `background:${color[num % color.length].value}; ${btnStyle}; margin-left:0` }); // reprintBtn.setAttribute('value', text); reprintBtn.addEventListener('click', () => { updateClipboard(text) }); eleMeta.append(reprintBtn); num++; } } function importantFollow() { let num = 0; const parseEleUrl = (eleUrl) => { if (!eleUrl) { return undefined; } const url = eleUrl.getAttribute('content'); return { url: url, key: url ? url.split('/').pop() : '', } }; for (let item of document.querySelectorAll('div[class~="TopstoryItem"]')) { const eleUrls = item.querySelectorAll('meta[itemprop="url"]'); if (!eleUrls) { continue; } const author = parseEleUrl(eleUrls[0]); const question = parseEleUrl(eleUrls[1]); const answer = parseEleUrl(eleUrls[2]); if (!(author && question && answer)) { continue; } const cacheKey = `${author.key},${question.key},${answer.key}`; if (sessionStorage.getItem(cacheKey)) { continue; } const eleMeta = item.querySelector('div[class="FeedSource"]'); const reprintBtn = createEle('button', '重点关注', {style: `background:${color[num % color.length].value}; ${btnStyle}; margin-left:0`}); // // reprintBtn.setAttribute('value', text); // reprintBtn.addEventListener('click', () => { // updateClipboard(text) // }); eleMeta.append(reprintBtn); sessionStorage.setItem(cacheKey, '1'); num++; } } window.onload = (e) => { // 屏蔽热榜和屏蔽活动栏 if (location.href === urlZhiHuFeed || reUrlZhiHuFollow.test(location.href)) { // 屏蔽热榜 blockTopStoryHot(); // 屏蔽活动栏 blockActivity(); // 屏蔽顶部栏的发现按钮 block(document.querySelector('a[href="//www.zhihu.com/explore"]').parentElement); // 屏蔽顶部栏等你来答 block(document.querySelector('a[href="//www.zhihu.com/question/waiting"]').parentElement) // 屏蔽搜索框 placeholder document.getElementsByTagName('input')[0].placeholder = ''; } // 对知乎首页的优化 if (location.href === urlZhiHuFeed) { // 过滤推荐 addBtnDisplayQuestion(); // 跳转到关注页面 document.querySelector('a[href="/follow"]').click(); } }; // follow 页去广告 setInterval(() => { if (reUrlZhiHuFollow.test(location.href)) { block(document.querySelectorAll('div[class~="TopstoryItem--advertCard"]')); } }, 200); window.addEventListener('scroll', debounce(() => { // follow 页添加重点关注按钮 if (reUrlZhiHuFollow.test(location.href)) { importantFollow(); // 问题页增加转载按钮 } else if (reUrlZhiHuQuestion.test(location.href)) { addReprintBtn(); } }, 100)); })();