您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Block / Hide "Sponsored" posts on Facebook
- // ==UserScript==
- // @name AdBlock for Facebook
- // @namespace fb-adblock
- // @version 1.6
- // @description Block / Hide "Sponsored" posts on Facebook
- // @author Thor Lancaster
- // @match https://www.facebook.com/*
- // @grant none
- // ==/UserScript==
- // Add abDbg=true as a URL parameter to debug ad classification
- (function() {
- 'use strict';
- var initialWait = 1500;
- setTimeout(function(){
- if(document.getElementById("stream_pagelet") == null){
- console.log("AdBlock for Facebook currently only works on news feeds. Aborting.");
- return;
- }
- console.log("AdBlock for Facebook running");
- document.abDbg = window.location.href.includes("abDbg=true");
- document.abCheckAll = false; // If true, check every post every time. Comsumes more CPU
- document.abTestCheck = null; // Set to an element for debugging to determine if this script thinks it's an ad
- var el = (document.getElementById("stream_pagelet"));
- var feed = el.querySelectorAll('[role="feed"]')[0];
- setInterval(function(f){
- try{
- checkAds(f);
- if(document.abTestCheck != null){ // Check test element to determine whether it is an article and/or an and
- var el = document.abTestCheck;
- document.abTestCheck = null;
- if(!el.getAttribute("role") == "article"){
- console.log("Element is not an article");
- }
- if(isAd(el)){
- console.log("Element is an ad");
- } else {
- console.log("Element is not an ad");
- }
- }
- } catch(e){ // Log error before it is swallowed by FB's obfusicated debugging maw
- console.error(e);
- }
- }, 2000, document);
- // TODO check for ads when feed updates rather than every 2 seconds
- }, initialWait);
- function checkAds(feed){
- document.lastABRun = new Date().getTime();
- var posts = feed.querySelectorAll('[role="article"]');
- for(var x = 0; x < posts.length; x++){
- var post = posts[x];
- // Calculate a quick checksum so that if text changes, the post will be re-scanned
- // I suspect that FB was creating non-ad posts and inserting them after a delay
- // To spoof the previous version of this script
- if(!post.abCheckSum || post.abCheckSum != abCheckSum(post) || document.abCheckAll){
- post.abCheckSum = abCheckSum(post);
- var isAdType = isAd(post);
- if(isAdType == 1){
- if(document.abDbg){
- markPost(post, "#F70");
- } else {
- removePost(post);
- }
- }
- // Blank post, should never happen
- else if(isAdType == -1){
- //console.log("ABCHECK blank post");
- }
- else if(isAdType == 0 && document.abDbg){
- markPost(post, "#0F7"); // for debugging
- }
- }
- }
- }
- // Color a FB post for debugging purposes
- function markPost(post, color){
- var els = post.querySelectorAll("*");
- for(var x = 0; x < els.length; x++){
- els[x].style.background = color;
- }
- }
- function removePost(post){
- post.parentElement.removeChild(post);
- //post.style.height = "0px";
- //post.style.opacity = "0";
- }
- function isAd(post){
- if(post.getAttribute("aria-label") == "Comment"){ // Don't scan comments for ads
- return 0;
- }
- var scan = post.innerText.substring(0, 128);
- if(scan.length == 0){
- return -1; // Blank post
- }
- if(scan.includes("·")){
- var start = scan.substring(0, scan.indexOf("·"));
- if(isSpnsrd(start)){
- //console.log("IS AN AD");
- return 1;
- }
- }
- //console.log("IS NOT AN AD");
- return 0;
- }
- // Scan for a string that represents "Sponsored"
- var SPONSORED = "Sponsored";
- function isSpnsrd(str){
- var spPtr = 0;
- for(var x = 0; x < str.length; x++){
- var chr = str[x];
- if(chr == SPONSORED[spPtr]){
- spPtr++;
- if(spPtr == SPONSORED.length){
- return true;
- }
- } else {
- var toReset = true;
- if(chr == "\n"){
- toReset = false;
- } else{
- for(var y = spPtr; y >= 0; y--){
- if(chr == SPONSORED[y]){
- toReset = false;
- }
- }
- }
- if(toReset){
- spPtr = 0;
- }
- }
- }
- return false;
- }
- // Calculate the checksum of an element through it's innerText
- function abCheckSum(el){
- return checkSum(el.innerText);
- }
- // Fast Checksum algorithm. Works great, open-source
- // See https://stackoverflow.com/questions/811195/fast-open-source-checksum-for-small-strings
- function checkSum(s)
- {
- var chk = 0x12345678;
- var len = s.length;
- for (var i = 0; i < len; i++) {
- chk += (s.charCodeAt(i) * (i + 1));
- }
- return (chk & 0xffffffff).toString(16);
- }
- })();