您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
2022/9/3 15:00:00
- // ==UserScript==
- // @name ZhihuOneKeyReport-JavaScript
- // @namespace Violentmonkey Scripts
- // @match https://www.zhihu.com/people/*
- // @require https://cdn.staticfile.org/jquery/3.4.1/jquery.min.js
- // @grant window.open
- // @grant window.focus
- // @version 1.1
- // @author 尼尼尼@知乎
- // @author 备份公众号:尼尼尼不打拳
- // @description 2022/9/3 15:00:00
- // @license GPL3
- // ==/UserScript==
- // 用于举报“不友善内容”时简化操作步骤的Javascript脚本。
- // 请勿滥用
- // 简要操作说明:
- // 1.在浏览器扩展商店中搜索“暴力猴“、”油猴“之类扩展插件,安装并启用。下面以”暴力猴“为例。
- // 2.在暴力猴插件中点击”+“号,新建JS脚本,将此脚本内容全部复制粘贴进去并保存。
- // 3.进入知乎主页,登录(不可用)知乎账户。在暴力猴插件控制台中启用上面保存的脚本。注意不能与单页回答检查脚本同时启用。
- // 4.刷新页面,右侧滚动条旁边会出多一个蓝色按钮(备用按钮,不是必须点击)
- // 5.进入要举报内容的个人主页, 点击回答、文章、想法等模块后,注意需要手工刷新一次页面。
- // 在每条内容后就会多出一个“一键举报”按钮。
- // 6.知乎的文章、回答等模块是部分动态加载的,所以有时候出现只有一半内容加上按钮的情况,
- // 这时点击一下右侧的蓝色按钮手工添加即可。
- (function () {
- 'use strict';
- // 开始对Modal窗口的变化监视,及提交处理。
- function handleModalSubmit(target){
- // Firefox和Chrome早期版本中带有前缀
- var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver
- // 创建Modal窗口的观察者对象
- var modalObserver = new MutationObserver(function (mutations) {
- try {
- mutations.forEach(function (mutation) {
- switch (mutation.type) {
- case 'childList':
- quickReport(modalObserver);
- throw new Error("模态窗口变化已检测到,抛出异常中止。")
- }
- });
- }catch (e){
- console.log(e);
- }
- });
- // 配置观察选项
- var config = {
- childList: true //观察目标子节点的变化,添加或者删除
- }
- // 传入目标节点和观察选项
- modalObserver.observe(target, config);
- }
- function handlePopMenuObserver(observer) {
- // 终止对pop menu的observer监控
- observer.disconnect();
- // 开始处理Modal窗口的提交
- var target = document.querySelector('div[class="Modal-content"]');
- handleModalSubmit(target)
- }
- function handleNormalReport(reportBtn){
- var originalReportBtn = reportBtn.previousElementSibling;
- if(originalReportBtn === null ){
- console.log('错误: 未查找到原始举报按钮');
- }
- originalReportBtn.click();
- var target = document.querySelector('div[class="Modal-content"]');
- handleModalSubmit(target);
- }
- function handlePopMenuReport(reportBtn) {
- // 先点击pop menu,这里要注意选择button元素,才能click。不要选到外层的div.
- console.log('点击pop menu');
- var popMenu = reportBtn.previousElementSibling.firstChild;
- // 使用mutation observer监视点击pop menu后生成的原始举报按钮
- var docBody = document.querySelector('body');
- // Firefox和Chrome早期版本中带有前缀
- var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver
- var btn = null;
- // 创建pop menu的观察者对象
- var popMenuObserver = new MutationObserver(function (mutations) {
- try{
- mutations.forEach(function (mutation) {
- switch (mutation.type) {
- case 'childList':
- var selfMenu = document.querySelector('div[class="Menu AnswerItem-selfMenu"]');
- var nsl = selfMenu.childNodes;
- // console.log(nsl);
- for(let n of nsl){
- if(n.innerHTML === '举报'){
- btn = n;
- // console.log(btn);
- }
- }
- btn.click();
- handlePopMenuObserver(popMenuObserver);
- throw new Error("回答模块按钮栏的pop menu变化已检测到,抛出异常中止。")
- }
- });
- }
- catch(e) {
- console.log(e);
- }
- });
- var config = {
- childList: true //观察目标子节点的变化,添加或者删除
- }
- // 传入目标节点和观察选项
- popMenuObserver.observe(docBody, config);
- // 建立观察者后再点击下拉菜单
- popMenu.click();
- }
- function quickReport(observer) {
- var spanList = document.querySelectorAll('div[class="Modal-content"] span');
- // console.log(spanList);
- var reason = null;
- for (let i = 0; i < spanList.length; ++i) {
- let span = spanList[i]
- if (span.innerHTML === '辱骂、人身攻击等不友善行为') {
- reason = span.parentElement;
- }
- }
- // 终止对Modal窗口的变化监控
- observer.disconnect();
- reason.click();
- var dialog = document.querySelector('textarea[class="Input"]');
- dialog.innerHTML = '不友善,引发情绪对立';
- var btnArea = document.querySelector('textarea[class="Input"]').parentElement.nextSibling;
- var btnList = btnArea.childNodes;
- var btnOnDialog = null;
- for (let i = 0; i < btnList.length; ++i) {
- //console.log(btnList[i]);
- if (btnList[i].innerHTML === "举报") {
- btnOnDialog = btnList[i];
- break;
- }
- }
- console.log('准备点击');
- btnOnDialog.click();
- }
- // 一键举报按钮的关联事件
- function watchReasonLoad(e) {
- var reportBtn = e.target;
- //对于带弹出菜单和不带菜单的页面,需要作分别处理。
- var url = window.location.href;
- if(url.includes('answers')){
- console.log('回答页面有pop菜单,需要单独处理');
- handlePopMenuReport(reportBtn);
- }else{
- console.log('回答以外的页面通用处理');
- handleNormalReport(reportBtn);
- }
- }
- // 监听“回答”模块的内容框架中的加载情况。即等待回答的内容动态加载完成。
- function monitorAnswerTab() {
- // var answerBody = document.querySelector('div[class="ListShortcut"]');
- var answerBody = document.getElementById('Profile-answers');
- // Firefox和Chrome早期版本中带有前缀
- var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver
- var answerObserver = new MutationObserver(function (mutations) {
- try {
- mutations.forEach(function (mutation) {
- switch (mutation.type) {
- case 'childList':
- console.log("进到这里说明内容是异步加载的,已加载完成")
- handlerContentObserver(answerObserver);
- // 这里有多个ChildList的变动,所以这里执行一次之后,要跳出foreach。
- // 不然会将堆栈中记录的所有变化遍历一次,重复执行。
- throw new Error('内容模块已加载,抛出异常中止多余的遍历');
- }
- });
- }catch(e){
- console.log(e);
- }
- });
- var config = {
- childList: true,
- subtree: true
- }
- // 传入目标节点和观察选项
- answerObserver.observe(answerBody, config);
- }
- // 处理回答的obeserver的回调函数
- function handlerContentObserver(answerObserver) {
- //终止监视
- answerObserver.disconnect();
- // 内容加载后,执行初始化
- console.log("内容加载后,执行初始化")
- init();
- }
- // 在每个"举报"按钮后添加"一键举报"按钮。
- // 想法和文章模块,是一部分随请求返回,另一部分异步加载。不保证每次都能全部添加上。
- function addReportButton() {
- var btnBarList = document.querySelectorAll('div[class="ContentItem-actions"]');
- //btnBarList = document.getElementsByClassName('ContentItem-actions');
- console.log("开始添加按钮")
- // 如果该Tab下一条内容都没有,直接return
- if (btnBarList.length === 0 ) {
- console.log("发生错误: 内容尚未加载,需手动点击右侧按钮注入");
- return;
- }
- for (let item of btnBarList) {
- // 视频模块的内容操作栏的结果与其它不同,多套了两层div, 需要单独处理。
- var url = window.location.href;
- if(url.includes('/zvideos')){
- let newItem = item.firstChild.firstChild;
- // console.log(newItem);
- newItem.insertAdjacentHTML('beforeend', '<button id="OneKeyReport" type="button" class="one-key-report" style="color:blue"> 【一键举报】</button>');
- }else{
- // 其它模块正常处理
- //$(item).append('<button id="OneKeyReport" type="button" class="one-key-report"> 【一键举报】</button>');
- item.insertAdjacentHTML('beforeend', '<button id="OneKeyReport" type="button" class="one-key-report" style="color:blue"> 【一键举报】</button>');
- }
- }
- // 遍历,给所有新增按钮注册(不可用)事件
- var oneKeyReportList = document.querySelectorAll('button[class="one-key-report"]');
- for (let item of oneKeyReportList) {
- item.addEventListener("click", watchReasonLoad, false);
- }
- console.log('添加新按钮完毕');
- }
- // 在每个翻页按钮中绑定刷新页面的event listener
- function addPageBtnEvent() {
- var pageBtnList = document.querySelectorAll('div[class="Pagination"] > button');
- //console.log(pageBtnList);
- //如果没有翻页栏,直接return
- if(pageBtnList === null){
- return;
- }
- for (let item of pageBtnList) {
- //item.addEventListener("click", addReportButton, false);
- item.addEventListener("click", refreshPage, false);
- }
- console.log('翻页按钮添加事件完成');
- }
- // 翻页后一次刷新,保证显示新增按钮
- function refreshPage(e){
- console.log(e.target)
- console.log("自动刷新页面");
- e.target.click();
- window.location.reload();
- }
- // 监视翻页栏的的翻页变化, 发布变化时则执行添加按钮和刷新的操作
- // function observePageBar() {
- // // Firefox和Chrome早期版本中带有前缀
- // var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver
- //
- // // 创建翻页栏的观察者对象
- // var targetPageBar = document.querySelector('div[class="Pagination"]');
- // console.log("找翻页栏");
- // console.log(targetPageBar);
- // //如果当前Tab没有翻页栏,直接return,不用监视了
- // if(targetPageBar === null){
- // console.log("本页没有翻页栏");
- // return;
- // }
- // var pageObserver = new MutationObserver(function (mutations) {
- // mutations.forEach(function (mutation) {
- // switch (mutation.type) {
- // case 'childList':
- // console.log(mutation);
- // console.log("发生翻页了===========");
- // addReportButton();
- // addPageBtnEvent(); // 因为页码元素会发生变化,所以每次都重新绑定
- // break;
- // }
- // });
- // });
- // // 配置观察选项,翻页栏监听子元素的变化
- // var config = {
- // childList: true,
- // subtree: true,
- // attributes:true
- // }
- // // 传入目标节点和观察选项
- // pageObserver.observe(targetPageBar, config);
- // }
- function init(){
- // 先开始监听个人主页中回答模块内容的动态加载。
- // 知乎的回答模块的内容全部是动态加载, 还好办。
- // 想法和文章模块,则是一部分内容随请求返回,另一部分又是异步加载,这种处理起来很麻烦,靠手动按钮弥补。
- var url = window.location.href;
- if(url.includes('/answers')){
- console.log("当前为回答模块, 单独处理");
- // 如果目标内容没有加载,则开始监听;如果已经加载,则直接在下面作普通初始化
- var answerContent = document.querySelectorAll('div[class="ContentItem-actions"]');
- if(answerContent.length === 0){
- console.log("回答模块的内容还没有加载,开始监听");
- monitorAnswerTab();
- }
- }
- //回答之外的模块作普通初始化处理
- // 添加一键举报按钮
- addReportButton();
- // 在每个翻页按钮中绑定 listener
- addPageBtnEvent();
- // 取消监视翻页栏的的翻页变化, 通过每次翻页时重新加载页面,来重新绑定事件,不然容易循环调用。
- // observePageBar();
- }
- // 添加手动插入举报按钮
- function addFloatButton() {
- $('body').append('<div id="FloatButton">点<br>击<br>添<br>加<br>一<br>键<br>举<br>报</div>')
- $('#FloatButton').css('width', '20px')
- $('#FloatButton').css('position', 'fixed')
- $('#FloatButton').css('top', '150px')
- $('#FloatButton').css('right', '3px')
- $('#FloatButton').css('background-color', '#2F4F4F')
- $('#FloatButton').css('color', 'white')
- $('#FloatButton').css('font-size', 'small')
- $('#FloatButton').css('z-index', 100)
- $('#FloatButton').css('border-radius', '25px')
- $('#FloatButton').css('text-align', 'center')
- $('#FloatButton').css('cursor', 'default')
- $('#FloatButton').click(function () {
- init();
- });
- }
- document.onreadystatechange = function () {
- if (document.readyState === "complete") {
- console.log('添加手动插入举报按钮');
- addFloatButton();
- // 进行初始化
- init();
- }
- }
- }
- )();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址