A couple notes:
- I currently have it set to only work on the front page (www.bogleheads.org) because that's what I use. I have not tested on the forum pages.
- Removed threads will remain hidden until your cookies are cleared, but again, this only applies to the front page
I didn't want to add any clutter to the front page, so I had ChatGPT only show the removal icon ("x") for a particular thread row when you hover over the correct area, which is the far right side of the row right before the white rectangular background ends. When the "x" appears the entire row will also turn grey so that it's easy to see what row the "x" corresponds to. Click the "x" and the thread will disappear!
You can make use of this userscript by installing the tampermonkey browser extension in your web browser (https://www.tampermonkey.net/)
Here's what it looks like (screen grab doesn't show mouse pointer which is near the "x"):

I've added the script to Greasyfork: https://greasyfork.org/en/scripts/45975 ... front-page
And here's the code if anyone is interested in seeing it:
Code: Select all
// ==UserScript==
// @name Hide Threads on Bogleheads
// @namespace https://www.bogleheads.org/
// @version 0.1
// @description Allows you hide a thread by clicking an "x" button that appears on rollover of the right side of each row
// @author ChatGPT
// @match https://www.bogleheads.org/*
// @exclude https://www.bogleheads.org/forum/*
// @exclude https://www.bogleheads.org/wiki/*
// @exclude https://www.bogleheads.org/blog/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
// Select the table with the ID of posts_table
const table = document.getElementById("posts_table");
if (!table) {
return;
}
// Select all rows in the main thread list
const rows = table.querySelectorAll("tbody tr");
// Load the list of hidden thread titles from local storage
const hiddenThreadTitles = JSON.parse(localStorage.getItem("hiddenThreadTitles") || "{}");
// Iterate over each row
for (let i = 0; i < rows.length; i++) {
const row = rows[i];
// ignore header rows by skipping rows with less than 5 td elements
if (row.getElementsByTagName("td").length < 5) {
continue;
}
// Select the first link in the row
const link = row.querySelector("td a");
if (!link) {
continue;
}
// Get the text of the link
const title = link.innerHTML;
// If the link text is in the list of hidden thread titles, hide the row
if (hiddenThreadTitles[title]) {
row.style.display = "none";
}
// Create a span element to hold the button
const span = document.createElement("span");
span.style.float = "right";
span.style.marginTop = "-0.5em";
span.style.opacity = "0";
span.style.display = "inline-block";
// Create a button element
const button = document.createElement("button");
button.innerHTML = "×";
button.style.background = "none";
button.style.border = "none";
button.style.cursor = "pointer";
button.style.fontSize = "smaller";
button.style.height = "1em";
button.style.lineHeight = "1em";
button.style.width = "1em";
button.style.position = "relative";
button.style.top = "5px";
// Add the button to the span
span.appendChild(button);
// Add the span to the row
row.appendChild(span);
// Attach a hover event listener to the span
span.addEventListener("mouseover", function() {
// When the span is hovered over, show the button
span.style.opacity = "1";
});
span.addEventListener("mouseout", function() {
// When the mouse moves out of the span, hide the button
span.style.opacity = "0";
});
// Attach a click event listener to the button
button.addEventListener("click", function() {
// When the button is clicked, hide the row
row.style.display = "none";
// Add the title of the hidden thread to the list of hidden thread titles
hiddenThreadTitles[title] = true;
// Store the list of hidden thread titles in local storage
localStorage.setItem("hiddenThreadTitles", JSON.stringify(hiddenThreadTitles));
});
button.addEventListener("mouseenter", function() {
row.style.backgroundColor = "#f2f2f2";
});
button.addEventListener("mouseleave", function() {
row.style.backgroundColor = "";
});
}
})();