您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
通過網頁操作, 達成屏蔽與解除屏蔽使用者
// ==UserScript== // @name BanYouSb // @namespace http://tampermonkey.net/ // @version 1.41 // @description 通過網頁操作, 達成屏蔽與解除屏蔽使用者 // @author RogerYeah // @match *://jandan.net/* // @icon https://www.google.com/s2/favicons?sz=64&domain=jandan.net // @grant none // ==/UserScript== (function () { // 檢查 localStorage 中是否存在 banCode 鍵值對 , 若不存在則新增一個空物件 const BAN_CODE_KEY = 'banCode'; function initializeBanCode() { try { const banCode = localStorage.getItem(BAN_CODE_KEY); if (!banCode) { localStorage.setItem(BAN_CODE_KEY, '{}'); } else { console.log('Here is who you ban: ' + banCode); } } catch (error) { console.error('Error accessing localStorage:', error); } } initializeBanCode(); // 將 localStorage 中的 banCode 鍵值對解析為 JSON 物件 var banCode = JSON.parse(localStorage.getItem(BAN_CODE_KEY)) // 獲取網頁中的所有評論列表 var comment = document.getElementsByClassName("commentlist") var lis = comment[0].getElementsByTagName("li") // 獲取網頁中的所有 .text 元素 var row = document.querySelectorAll('.text') // 定義屏蔽按鈕 var voteElements = document.querySelectorAll(".jandan-vote") // 定義吐槽按鈕 var tucao = document.querySelectorAll(".tucao-btn") //定義 unban 函式 function unban(e) { // 獲取 li 元素 var li = e.parentNode.parentNode.parentNode; // 獲取作者姓名 var author = li.getElementsByClassName("author")[0].getElementsByTagName("strong")[0].textContent; // 確認是否解除屏蔽 if (confirm("讓我看看 " + author + " 這傢夥有什麼長進")) { // 從 banCode 物件中刪除 author 對應的鍵值對 delete banCode[author]; // 將更新後的 banCode 物件存入 localStorage localStorage.setItem(BAN_CODE_KEY, JSON.stringify(banCode)); // 重新載入頁面 location.reload(); } } // 定義 ban 函式 function ban(e) { // 獲取 li 元素 var li = e.parentNode.parentNode.parentNode; // 獲取作者姓名 var author = li.getElementsByClassName("author")[0].children[0]; // 獲取作者防偽碼 var privCode = author.getAttribute('title').split('防伪码:').pop(); // 確認是否屏蔽 if (confirm("您確定要屏蔽 " + author.textContent + " 嗎?")) { // 將作者姓名和防偽碼新增至 banCode 物件中 banCode[author.textContent] = privCode; // 將更新後的 banCode 物件存入 localStorage localStorage.setItem(BAN_CODE_KEY, JSON.stringify(banCode)); // 重新載入頁面 location.reload(); } } // 定義 unBanUser 函式 function unBanUser(e) { // 確認是否解除屏蔽 if (confirm("讓我看看 " + e + " 這傢夥有什麼長進")) { // 從 banCode 物件中刪除 author 對應的鍵值對 delete banCode[e]; // 將更新後的 banCode 物件存入 localStorage localStorage.setItem(BAN_CODE_KEY, JSON.stringify(banCode)); // 重新載入頁面 location.reload(); } } // 定義吐槽屏蔽函式 function tucaoHandle(e) { const bannedUsers = JSON.parse(localStorage.getItem("banCode")); const bannedUsernames = Object.keys(bannedUsers); const isFBan = localStorage.getItem('FBan') === 'true'; const tucaoList = e.querySelectorAll('.tucao-list .tucao-row'); const tucaoHotList = e.querySelectorAll('.tucao-hot .tucao-row'); let rowsToDelete = []; if (!bannedUsers) return; // 如果 banCode 為空,則直接返回 bannedUsernames.forEach(bannedUser => { rowsToDelete = []; // 找到所有需要刪除的元素,並存儲到 rowsToDelete 陣列中 tucaoList.forEach(row => { const tucaoAuthor = row.querySelector('.tucao-author'); if (tucaoAuthor && tucaoAuthor.textContent.includes(bannedUser)) { rowsToDelete.push(row.id); } }); // 熱榜屏蔽 tucaoHotList.forEach(row => { const tucaoAuthor = row.querySelector('.tucao-author'); if (tucaoAuthor && tucaoAuthor.textContent.includes(bannedUser)) { rowsToDelete.push(row.id); } }); }); if (isFBan) { rowsToDelete.forEach(row => { document.getElementById(row).remove() }); } else { rowsToDelete.forEach(row => { var rowItem = document.getElementById(row); var contentBox = rowItem.querySelector(".tucao-content"); var content = contentBox.textContent; document.getElementById(row).querySelector(".tucao-content").innerHTML = ` <del class="delete"> <span class="math-inline">已屏蔽</span> </del> <i class="peep" title="${content}">偷看一下(懸停)</i> `; }); } } // 屏蔽防偽碼標記用戶 for (let i = lis.length - 1; i >= 0; i--) { // 獲取作者姓名 const author = lis[i].querySelector(".author strong"); const authorName = author ? author.innerText : ''; // 遍歷 banCode 物件中的所有鍵值對 for (const [bannedAuthor, _] of Object.entries(banCode)) { // 若作者姓名與 banCode 物件中的鍵值對匹配 且 FBan Mode 為真 if (authorName === bannedAuthor && localStorage.getItem('FBan') === 'true') { console.log(lis[i].remove()); } else if(authorName === bannedAuthor) { // 獲取評論內容 const contentBox = lis[i].querySelector(".text"); const img = lis[i].querySelector("img"); const content = contentBox.querySelector('p:not(.bad_content)').textContent.replace(/<br>/g, ' '); // 將評論內容替換為 "[已屏蔽]" 標記 contentBox.innerHTML = ` <del class="delete"> <span class="math-inline">${authorName} - 已屏蔽</span> </del> <i class="peep" title="${content}">偷看一下(懸停) ${img != null ? `<img style="opacity: 0;" src="${img.src}" alt="pic" />`: ''} </i> `; break; } } } // 遍歷所有 .jandan-vote 元素 for (var x = 0; x < voteElements.length; x++) { // 創建一個新的 a 元素 var button = document.createElement("a"); // 若評論內容包含 "[已屏蔽]" 標記 if (row[x].innerHTML.includes('del')) { // 設定按鈕文字為 "[解除屏蔽]" button.textContent = "[解除屏蔽]"; // 為按鈕添加點擊解除屏蔽函式 button.addEventListener("click", function () { unban(this); }); } else { // 設定按鈕文字為 "[屏蔽]" button.textContent = "[屏蔽]"; // 為按鈕添加點擊屏蔽函式 button.addEventListener("click", function () { ban(this); }); } // 設定按鈕顏色為 "#c8c7cc" button.style.color = "#c8c7cc"; // 將按鈕插入到 .jandan-vote 元素的開頭 voteElements[x].prepend(button); } // 生成list按鈕Dom var counter = Object.keys(banCode).length var listDom = ` <div class="banList"> <div class="toggleArea"> <div class="banModeSwitch" title="打開此開關完全屏蔽模式, 開啟後偷看功能關閉並完全屏蔽列表中的使用者(看不見任何與屏蔽使用者相關之項目)"> <div class="switch ${localStorage.getItem('FBan') === 'true' ? 'active' : ''}" id="switch"></div> <span>FBan Mode</span> </div> 屏蔽列表 <div class="toggleList"> <span class="toggleList-show">+</span> <span class="toggleList-hide" style="display: none;">-</span> </div> </div> <ul class="mainList" style="display: none;"> ` // 循環遍歷 banCode 對象中的已屏蔽用戶 for (var li = 0; li < counter; li++) { listDom += ` <li class="mainList-item">${Object.keys(banCode)[li]} <a class="unban" href="javascript: void();">x</a></li> ` } listDom += ` </ul> <form id="banForm"> <input class="ban-input" type="text" placeholder="手動屏蔽(鍵入ID後, 猛擊Enter)" /> </form> </div> ` // 獲取 DOM 元素 const wrapper = document.getElementById('wrapper'); const listDomElement = document.createElement('div'); listDomElement.innerHTML = listDom; wrapper.appendChild(listDomElement); // 添加點擊事件監聽器,用於處理刪除按鈕的點擊 wrapper.addEventListener('click', (event) => { if (event.target.classList.contains('unban') && !event.target.classList.contains('clicked')) { const username = event.target.parentNode.textContent.trim().replace(' x', ''); unBanUser(username); event.target.classList.add('clicked') } if (event.target.classList.contains('tucao-btn') && !event.target.classList.contains('clicked')) { var tucaoId = event.target.dataset.id; var tucaoBox = document.getElementById(`jandan-tucao-${tucaoId}`) var intervalBox = setInterval(() => { if (tucaoBox.innerText !== "数据加载中....biubiubiu....") { tucaoHandle(tucaoBox); clearInterval(intervalBox); event.target.classList.add('clicked') } }, 100); } }); // 獲取 DOM 元素 const switcher = document.getElementById('switch'); switcher.addEventListener('click', (event) => { if(localStorage.getItem('FBan') !== null) { const isFBan = localStorage.getItem('FBan') === 'true'; localStorage.setItem('FBan', !isFBan); switcher.classList.toggle('active', !isFBan); location.reload(); } else { if(confirm('打開此開關完全屏蔽模式, 開啟後偷看功能關閉並完全屏蔽列表中的使用者(看不見任何與被屏蔽使用者相關之項目)')) { const isFBan = localStorage.getItem('FBan') === 'true'; localStorage.setItem('FBan', !isFBan); switcher.classList.toggle('active', !isFBan); location.reload(); } } }) // 獲取並緩存屏蔽用戶列表 DOM 元素 const toggleList = document.querySelector('.toggleList'); if(toggleList != null) { // 添加點擊事件監聽器,用於展開/收起屏蔽用戶列表 toggleList.addEventListener('click', function() { const secondSpan = this.querySelector('span:nth-of-type(2)'); const ul = document.querySelector('.mainList'); secondSpan.style.display = secondSpan.style.display === 'none' ? 'block' : 'none'; ul.style.display = ul.style.display === 'none' ? 'block' : 'none'; }); } // 手動屏蔽功能 const myForm = document.getElementById('banForm'); const myInput = document.querySelector('.ban-input'); myForm.addEventListener('submit', function() { const inputValue = myInput.value; if (confirm("此屏蔽無法正確辨識身分, 換個暱稱就屏蔽不了了, 您確定要屏蔽 " + inputValue + " 嗎?")) { let banData = JSON.parse(localStorage.getItem("banCode")) || {}; // 初始化為空物件 if (banData[inputValue] == undefined) { // 避免重複添加 banData[inputValue] = null; localStorage.setItem("banCode", JSON.stringify(banData)); setTimeout(() => { location.reload(); }, 100) } else { alert("該用戶已經被屏蔽"); } } }); setTimeout(() => { // 創建 style 元素 var style = document.createElement('style'); // 創建文本,包含 CSS 規則 style.innerHTML = ` .commentlist .row { overflow: visible; } .delete { display: inline-block; margin-bottom: 20px; margin-top: 7px; margin-right: 5px; } .tucao-content { .delete { display: inline-block; margin: 0; } } .peep { display: inline-block; position: relative; font-size: 10px; img { position: absolute; left: calc(100% + 10px); opacity: 0; max-width: 250px !important; pointer-events: none; } &:hover img { opacity: 1 !important; transition: .5s ease; } } .banList { display: flex; flex-wrap: wrap; justify-content: flex-end; position: fixed; top: 84px; width: 1184px; pointer-events: none; width: calc((100vw - 984px - 60px) / 2); max-height: calc(100% - 300px); box-sizing: border-box; left: calc(100% - (100vw - 984px - 30px) / 2); } .toggleArea { padding: 5px; position: relative; text-align: center; width: 100%; border-radius: 5px; background: #bababa; color: #333; font-weight: bold; pointer-events: auto; .toggleList { display: inline-block; position: absolute; width: 20px; height: 20px; right: 5px; &-show, &-hide { position: relative; display: inline-block; width: 20px; height: 20px; background: #bababa; &:hover { color: #666; } } &-hide { position: absolute; top: 0; } } } .mainList { margin-bottom: 3px; position: relative; width: 90px; top: calc(100% + 10px); display: none; width: 100%; color: gray; overflow: auto; height: calc(100vh - 196px); &-item { margin-bottom: 4px; padding-bottom: 4px; width: 100%; border-bottom: 1px solid gray; font-size: 12px; white-space:nowrap; text-overflow:ellipsis; -o-text-overflow:ellipsis; overflow: hidden; max-width: 100%; padding-right: 20px; box-sizing: border-box; .unban { pointer-events: auto; cursor: pointer; position: absolute; right: 0; } } } #banForm { position: absolute; bottom: calc(100% + 5px); left: 0; width: 100%; pointer-events: auto; .ban-input { position: relative; width: 100%; border-color: #d8d8d8; border-width: 0px 00px 1px 0px; &:focus { outline: none; } &::placeholder { color: #d8d8d8; } } } .banModeSwitch { position: absolute; top: 5px; height: 20px; .switch { position: relative; width: 20px; height: 10px;; border-radius: 10px; background: rgb(255 255 255 / 40%); &:after { content: ''; display: block; position: absolute; top: 2px; left: 2px; height: 6px; width: 6px; border-radius: 10px; background: rgb(0 0 0 / 20%); } &.active { background: rgb(187 255 204 / 40%); &:after { left: auto; right: 2px; background: rgb(22 165 0 / 40%); } } } span { padding-top: 2px; display: block; color: #333 !important; font-size: 7px; font-weight: 100; } } #nav_top { z-index: 99999; } `; document.head.appendChild(style); }, 1); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址