您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Hides sponsored posts in FB's news-feed (Sept 2021)
当前为
// ==UserScript== // @name facebook - ad block v3 // @version 3.07 // @description Hides sponsored posts in FB's news-feed (Sept 2021) // @author zbluebugz // @match https://*.facebook.com/* // @run-at document-idle // @namespace https://gf.qytechs.cn/users/812551 // ==/UserScript== /* Comments: original: https://pastebin.com/raw/vmaiA8jJ 05/09/2021: FB has changed the way sponsored posts are created - made harder to detect. 06/09/2021: Detected a couple of slight variations in how sponsored posts are created. 14/09/2021: Detected another slight variation in how sponsored posts are created. 14/09/2021: Fixed bug with getting textNode values. 18/09/2021: Detected another variation on how sponsored posts are created. 18/09/2021: Added code to detect 'Sponsored · Paid for by XYZ' (very rare - untested) 21/09/2021: Added Portuguese (requested by a user) 21/09/2021: Detected another variation on how sponsored posts are created. */ (function () { 'use strict'; const title = 'facebook - ad block'; // -- START KEYWORDS // Keyword: Sponsored posts' // - multivalue object; // - 'language code' : [ uses 'span' or 'b' elements, sponsored word ] // - (language code located in the HTML element) // - various non-sponsored keywords ... const SPONSORED_LIST = { // english 'en': ['span', 'Sponsored', 'People you may know', 'Suggested for you', 'Suggested Pages', 'Suggested Events', 'Paid partnership', 'Suggested groups'], // portuguese 'pt': ['b', 'Patrocinado', 'Pessoas que talvez conheças', 'Sugerido para você', 'Páginas sugeridas', 'Eventos Sugeridos', 'Parceria paga', 'Grupos sugeridos'] } // Hide certain promotional posts ... const TOGGLE_PEOPLE_YOU_MAY_KNOW = true; const TOGGLE_SUGGESTED_CONTENT = true; const TOGGLE_SUGGESTED_PAGES = true ; const TOGGLE_SUGGESTED_EVENTS = false; const TOGGLE_PAID_PARTNERSHIP = true; const TOGGLE_SUGGESTED_GROUPS = false; // Create Room - uses the data-pagelet attribute for detection. no language text required. const TOGGLE_CREATE_ROOM = true; // Sponsored paid for ... // *** untested as it is very rare ... *** const TOGGLE_SPONSORED_PAID_FOR = false; // - just match the first few words ... const SPONSORED_PAID_FOR_WORDS = 'Sponsored · Paid for by'; // -- END KEYWORDS // -- rest of code - no more keywords to adjust. // which language entry to use? const SPONSORED_OBJ = SPONSORED_LIST[document.querySelector('html').getAttribute('lang')] || SPONSORED_LIST.en; const SPONSORED_S_B = SPONSORED_OBJ[0].toUpperCase(); const SPONSORED_WORD = SPONSORED_OBJ[1]; // Keywords: text to find for certain promotional elements let suggestions = []; if(TOGGLE_PEOPLE_YOU_MAY_KNOW) suggestions.push(SPONSORED_OBJ[2]); if(TOGGLE_SUGGESTED_CONTENT) suggestions.push(SPONSORED_OBJ[3]); if(TOGGLE_SUGGESTED_PAGES) suggestions.push(SPONSORED_OBJ[4]); if(TOGGLE_SUGGESTED_EVENTS) suggestions.push(SPONSORED_OBJ[5]); if(TOGGLE_PAID_PARTNERSHIP) suggestions.push(SPONSORED_OBJ[6]); if(TOGGLE_SUGGESTED_GROUPS) suggestions.push(SPONSORED_OBJ[7]); // hide or highlight the selected posts let HIDE_STYLE = (true) ? 'display:none !important' : 'border:3px solid yellow !important'; // how often to run this script (milliseconds) const CHECK_RATE_MS = 100; // sponsored for posts - length of text let SPONSORED_PAID_FOR_WORDS_LEN = SPONSORED_PAID_FOR_WORDS.length; function hide(el) { return el.setAttribute('style',HIDE_STYLE); }; function doChanges() { if(TOGGLE_CREATE_ROOM){ let create_room = document.querySelector('div[data-pagelet="VideoChatHomeUnitNoDDD"]'); if(create_room) hide(create_room); }; function findSponsoredPosts() { // get collection of posts, ignore those already read by this script. let posts = Array.from( document.querySelectorAll('div[data-pagelet*=FeedUnit]:not([adbpr])') // next line for use in debugging - ignores the posts that have been already processed. //document.querySelectorAll('div[data-pagelet*=FeedUnit]') ); // loop through each post to see if it is a sponsored one or not let hidePosts = []; let csr ; // getComputedStyle results let ss = 1; // sponsored structure (1 = uses aria-label, 2 = uses a tag. let isFlagged = false; // has post been flagged as sponsored? posts.forEach( post => { // flag this post as not to be read/processed again post.setAttribute('adbpr', true); // reset isHidden flag isFlagged = false; // within this unread post, find the SPAN element(s) having aria-label = Sponsored // (usually only one is found) let alSpans = Array.from(post.querySelectorAll('span[aria-label="' + SPONSORED_WORD + '"]')); ss = 1; // console.info('----:', SPONSORED_WORD, alSpans.length ); if (alSpans.length === 0) { // sigh! uses the A tag structure; not language dependent. alSpans = Array.from(post.querySelectorAll('a[href="#"][aria-label="label"]')); ss = 2; } // is the word "Sponsored" visible? // - there are several spans having single letters - all randomised, but will make up "sponsored" when certain span tags are "visible". alSpans.forEach(sp => { let daText = ''; // get the next sibling from the <span aria-label="Sponsored"></span> let nsp ; if (ss === 1) { // uses the span[arial-label="sponsored] structure nsp = sp.nextSibling; } else { // uses the a[href=# aria-label=label] structure // - A tag is nested with 2 SPANs then B tag wrapper with lots of B tags. // - grab the first B tag (wrapper) nsp = sp.firstChild.firstChild.firstChild; } // console.info("--- nsp:", nsp) // note that this sibling is a "parent" ... // .. sometimes it has a textNode (as firstChild) ... if (SPONSORED_S_B === 'B') { // uses the <b> tags structure daText += nsp.innerText; //console.info("--->", daText); } else { // uses the <span> tags structure if (nsp.tagName === "SPAN") { if (nsp.firstChild.tagName === 'SPAN') { // no immediate textNode // - nothing to do. } else { csr = window.getComputedStyle(nsp); if (csr.position === 'relative' && csr.display === 'inline') { // visible ... (need both styles) // - ok, grab the textNode's value. daText += nsp.firstChild.textContent ; } } } //console.info("--::", daText); // the "parent" has childNodes (spans) ... nsp = nsp.firstChild; do { if (nsp.tagName === 'SPAN') { csr = window.getComputedStyle(nsp); if (csr.position === 'relative' && csr.display === 'inline') { // visible ... (need both styles) if (nsp.innerText.length ===1) { daText += nsp.innerText; } } } nsp = nsp.nextSibling; } while (nsp); } // console.info("--is Sponsored post:", daText, (SPONSORED_WORD.indexOf(daText) > -1)); //console.info("-----sp: ", sp); // do we hide this post? if (SPONSORED_WORD.indexOf(daText) > -1 ) { hidePosts.push(sp); isFlagged = true; } }); if (!isFlagged) { // post not yet marked to be hidden ... // .. so check for suggestions. if (suggestions) { // scan the a tags let els = Array.from(post.querySelectorAll('a')); let skip = false; for (let x = 0; x < els.length; x++) { if (suggestions.includes(els[x].textContent)) { hidePosts.push(els[x]); skip = true; break; } }; // scan the span tags if (!skip) { els = Array.from(post.querySelectorAll('span')); for (let x = 0; x < els.length; x++) { if (suggestions.includes(els[x].textContent)) { hidePosts.push(els[x]); break; } } } } // sponsored + paid for ... posts (untested) if (TOGGLE_SPONSORED_PAID_FOR) { let tdivs = Array.from(post.querySelectorAll('div[role="button"')); for (let x= 0; x < tdivs.length; x++) { if (tdivs[x].textContent.substring(0,SPONSORED_PAID_FOR_WORDS_LEN) === SPONSORED_PAID_FOR_WORDS) { hidePosts.push(tdivs[x]); break; } } } } } ); return hidePosts }; function kill(element) { try { if(element) { let limit = 0; while(limit++ < 100) { if(typeof element.getAttribute('data-pagelet') == 'string') { if(element.getAttribute('data-pagelet').contains('FeedUnit')) { hide(element); return; }; }; element = element.parentNode; }; }; } catch (e) { }; }; findSponsoredPosts().forEach( e => kill(e) ); }; const callback = function () { try { doChanges(); } catch (e) { console.warn(title, e); } }; setInterval(callback, CHECK_RATE_MS); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址