【油猴插件】话题预览

鼠标悬浮在话题上,预览话题的部分内容。

使用场景
愚人节防骗

比如标题吸引人点击的
image

比如以为是教程但却是在求助的
image

主要流程
为所有可点击的超链接(主要是论文中的话题)创建了监听器,当鼠标悬浮时,通过话题的链接获取话题的内容,并加入到缓存中,最后悬浮显示预览内容。

// ==UserScript==
// @name         论坛话题预览
// @namespace    https://linux.do/
// @version      0.2
// @description  Preview link content on mouse hover
// @author       zheng
// @match        https://linux.do/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=linux.do
// @grant        GM_addStyle
// @license MIT
// ==/UserScript==

(function () {
	"use strict";

	const contentCache = {};

	var previewPopup = document.createElement("div");
	previewPopup.id = "linkPreviewPopup";
	previewPopup.style.display = "none";
	previewPopup.style.position = "absolute";
	previewPopup.style.background = "#fff";
	previewPopup.style.border = "1px solid #ccc";
	previewPopup.style.padding = "10px";
	previewPopup.style.maxWidth = "300px";
	previewPopup.style.boxShadow = "3px 3px 5px rgba(0,0,0,0.3)";
	document.body.appendChild(previewPopup);

	// Add styles for preview popup
	GM_addStyle(`
      #linkPreviewPopup {
          z-index: 9999999;
      }
  `);

	// Function to fetch preview content
	async function getPreviewContent(linkHref) {
		try {
			if (contentCache[linkHref]) {
				console.log("Content found in cache:", contentCache[linkHref]);
				return contentCache[linkHref];
			}
			console.log("linkHref: " + linkHref);

            const response = await fetch(linkHref);
			if (!response.ok) {
				throw new Error("Network response was not ok");
			}
			const html = await response.text();

			// Create a temporary div element to hold the HTML content
			const tempDiv = document.createElement("div");
			tempDiv.innerHTML = html;
			const metaDescription = tempDiv.querySelector('meta[name="description"]');
			let descriptionContent = metaDescription ? metaDescription.getAttribute("content") : "";
			descriptionContent = descriptionContent.trim();
			contentCache[linkHref] = descriptionContent;

			console.log("Description content:", descriptionContent);
			return descriptionContent;
		} catch (error) {
			console.error("Error fetching link preview content:", error);
			return null;
		}
	}

	// Function to show preview popup
	function showPreviewPopup(link, event) {
		getPreviewContent(link)
			.then((previewContent) => {
				if (previewContent) {
					console.log("previewContent: " + previewContent);
					// Set preview content
					previewPopup.innerHTML = previewContent.replace(/<[^>]*>/g, '');

					// Position the preview popup
					previewPopup.style.top = event.pageY + 30 + "px";
					previewPopup.style.left = event.pageX + 10 + "px";

					// Show the preview popup
					previewPopup.style.display = "block";
				}
			})
			.catch((error) => {
				console.error("Error fetching link preview content:", error);
			});
	}

    function hidePreviewPopup() {
		previewPopup.style.display = "none";
	}

    $(document).on('mouseenter', 'a', function(event) {
        var target = $(event.target).closest('a');
        var url = target.attr('href');
        console.log("URL: " + url);
        console.log("Mouse enter");
        showPreviewPopup(url, event);
    });
    $(document).on('mouseout', 'a', function() {
        console.log("Mouse out");
        hidePreviewPopup();
    });

})();

18 个赞

油猴大军喜增一员大将

2 个赞

@delph1s 又来一个

3 个赞

是不是应该发送到油猴网站上去,更易传播

1 个赞

做得比较粗糙 比如或许可以显示更多的预览内容 比如话题的回复, 还有缓存的话也可以放到LocalStorage里面,但自用嘛,就没考虑太多

1 个赞

发布了一下 论坛话题预览

2 个赞

好东西,标题党太多了

1 个赞

Mark,加入集合

1 个赞

又有脚本,牛,谢谢

1 个赞

牛的

1 个赞

试试看啥效果,谢谢分享

1 个赞

带有“V50”内容的直接屏蔽更好了

1 个赞

匹配规则改成
// @match https://linux.do/*
会不会好一点

2 个赞

看个人喜好自己魔改代码吧

1 个赞

今天全是诈骗帖子,就是这个插件发光发热的最好时间 :rofl:

1 个赞

是的 之前只在主页测就没考虑到 然后在话题内的热门链接 因为DOM是

<a><span></span></a>

所以现在的代码直接监听超链接的hover也会有问题
image

1 个赞

确实,所以我现在自己设置成了在最新话题或者新话题中才会匹配

我修了一下 把话题内的话题也给加上预览了 虽然感觉没啥用

1 个赞

还真是 :rofl:

你太牛了,为层主点赞