From a27ca613add1f6bb00f18a9c2edf27f95e34be37 Mon Sep 17 00:00:00 2001 From: kuzen Date: Sun, 6 Feb 2022 18:15:58 +0800 Subject: [PATCH] feature: unblock --- README.md | 6 +- bili-recommended-list-blocker.js | 136 +++++++++++++++++++------------ 2 files changed, 90 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index e53ba15..f5efb49 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,13 @@ ## 功能 -- 在首页推荐和推广栏的视频卡片的右边会有一个屏蔽按钮,点击即可屏蔽该up主哦. +- 在首页推荐和推广栏的视频卡片的右边会有一个屏蔽按钮,点击即可屏蔽该up主哦。 +- 重复点击屏蔽按钮可取消屏蔽。 - 屏蔽了推广栏广告 github: -greasyfork: +greasyfork: ![20211224212815](https://s2.loli.net/2021/12/24/E4HL193jXkcWsdn.gif) @@ -17,6 +18,7 @@ greasyfork: { + setCardViewEvent(cv) { + cv.onmouseover = (ev) => { ev = ev || window.event; const target = ev.target; - if (target.parentElement.className.toLowerCase() === 'v-img bili-video-card__cover') { + if (target.parentElement.className === 'v-img bili-video-card__cover' || target.className === 'v-img bili-video-card__cover') { const cardView = target.closest('.bili-video-card__wrap'); const blockDiv = cardView.getElementsByClassName('brlb-block-btn')[0]; blockDiv.setAttribute('style', ''); } }; - recommendContainer.onmouseout = (ev) => { + cv.onmouseout = (ev) => { ev = ev || window.event; const target = ev.target; - if (ev.toElement.className.toLowerCase() === 'brlb-block-btn') { + if (ev.toElement != null && ev.toElement.className === 'brlb-block-btn') { return false; } - if (target.parentElement.className.toLowerCase() === 'v-img bili-video-card__cover') { + if (target.parentElement.className === 'v-img bili-video-card__cover' || target.className === 'v-img bili-video-card__cover') { const cardView = target.closest('.bili-video-card__wrap'); const blockDiv = cardView.getElementsByClassName('brlb-block-btn')[0]; blockDiv.setAttribute('style', 'display: none;'); @@ -831,36 +835,48 @@ recommendContainer.onclick = (ev) => { ev = ev || window.event; const target = ev.target; - console.log(target); if (target.className.toLowerCase() === 'brlb-block-btn') { - const cardView = target.parentElement; - const uid = this.getUid(cardView); + let cardView = target.parentElement; + const id = cardView.parentElement.dataset.brlbId; + let uid; + if (this.isAd(cardView)) { + uid = 0; + } else { + uid = this.getUid(cardView); + } if (uid != null) { - console.log(`${uid} 已屏蔽`); - if (this.blockList.add('uid', uid) === true) { - this.blockCardView(cardView, uid, -1); + if (cardView.parentElement.dataset.blocked == '1') { + console.log(`${uid} 取消屏蔽`); + this.blockList.remove('uid', uid.toString()); + cardView = this.unblockCardView(cardView, id); + this.addBlockBtn(cardView); + this.setCardViewEvent(cardView); + } else { + if (this.blockList.add('uid', uid.toString()) === true){ + console.log(`${uid} 已屏蔽`); + cardView = this.blockCardView(cardView, uid); + this.addBlockBtn(cardView); + this.setCardViewEvent(cardView); + } } - this.addBlockBtn(cardView); - this.setCardViewEvent(cardView); } + cardView.parentElement.dataset.brlbId = id; } }; } - blockCardView(cardView, uid, index) { + blockCardView(cardView, uid) { const newCardView = createElement('div', { 'className': 'bili-video-card__wrap __scale-wrap brlb-block', - 'data-uid': uid.toString(), - 'data-id': index.toString(), }, []); newCardView.innerHTML = ` - +
-
+
`; + cardView.replaceWith(newCardView); + newCardView.parentElement.dataset.blocked = '1'; + newCardView.parentElement.dataset.brlbUid = uid.toString(); + return newCardView; + } + + unblockCardView(cardView, id) { + // 再次点击取消屏蔽 + const cv = this.history[cardView.parentElement.parentElement.className][id]; + cardView.replaceWith(cv); + cv.parentElement.dataset.blocked = '0'; + return cv; } getUid(cardView) { @@ -885,7 +913,7 @@ const uid = owner.substr(owner.lastIndexOf('/') + 1); return uid; } else { - return null; + return cardView.parentElement.dataset.brlbUid; } } @@ -893,31 +921,44 @@ return cardView.getElementsByClassName('bili-video-card__info--ad-img').length > 0; } + // 换一换 + rollObserver(recommendContainer) { + const rollCallback = (mutationsList, observer) => { + const recommendList = recommendContainer.getElementsByClassName('bili-video-card__wrap'); + this.history[recommendContainer.className] = Array.from(recommendList); + this.run(recommendList); + }; + const rollObse = new MutationObserver(rollCallback); + const config = {attributes: false, childList: true, subtree: false}; + rollObse.observe(recommendContainer, config); + } + register(container) { const cardViewList = container.getElementsByClassName('bili-video-card__wrap'); + this.history[container.className] = Array.from(cardViewList); this.run(cardViewList); - this.setCardViewEvent(cardViewList); this.setBlockBtnEvent(container); } run(cardViewList) { - for (const cardView of cardViewList) { + let index = 0; + for (let cardView of cardViewList) { if (this.isAd(cardView)) { - // 推广链接 - this.blockCardView(cardView, 0, -1); + // 广告 + cardView = this.blockCardView(cardView, 0); this.addBlockBtn(cardView); this.setCardViewEvent(cardView); } else { // 普通视频 const uid = this.getUid(cardView); - if (uid != null) { - if (this.blockList.isContained('uid', uid)) { - this.blockCardView(cardView, uid, -1); - } + if (uid != null && this.blockList.isContained('uid', uid) === true) { + cardView = this.blockCardView(cardView, uid); } this.addBlockBtn(cardView); this.setCardViewEvent(cardView); } + cardView.parentElement.dataset.brlbId = index.toString(); + index++; } } } @@ -925,6 +966,7 @@ class BlockList { constructor() { this.list = JSON.parse(GM_getValue('blockList') || '{"uid":[],"username":[],"title":[]}'); + // 历史遗留问题( if (this.list instanceof Array) { this.list = {'uid': this.list, 'username': [], 'title': []}; } @@ -932,6 +974,7 @@ this.list[key] = this.list[key].sort(); this.removeDuplicates(key); }); + console.log(`黑名单列表:`); console.log(this.list); } @@ -964,7 +1007,7 @@ } clr() { - console.log('清空黑名单'); + console.log(`清空黑名单`); GM_setValue('blockList', '{"uid":[],"username":[],"title":[]}'); this.list = {'uid': [], 'username': [], 'title': []}; } @@ -1051,20 +1094,13 @@ const biliBlocker = new BiliBlocker(blockList, true); const recommendContainer = document.querySelectorAll('div[class^="recommend-container__"]')[0]; if (recommendContainer != null) { - const evaContainer = document.querySelectorAll('div[class^="eva-extension-area"]')[0]; + const evaContainer = document.querySelectorAll('div[class^="eva-extension-body"]')[0]; biliBlocker.register(recommendContainer); biliBlocker.register(evaContainer); // 延迟一会,避免重复处理 setTimeout(() => { - // 换一换 - const rollCallback = (mutationsList, observer) => { - const recommendList = recommendContainer.getElementsByClassName('bili-video-card__wrap'); - biliBlocker.run(recommendList); - }; - const rollObserver = new MutationObserver(rollCallback); - const config = {attributes: false, childList: true, subtree: false}; - rollObserver.observe(recommendContainer, config); + biliBlocker.rollObserver(recommendContainer); }, 100); } }, false);