Greasy Fork

Greasy Fork is available in English.

nodeseek首页悬浮展示帖子详情

鼠标悬浮展示nodeseek帖子详情

// ==UserScript==
// @name         nodeseek首页悬浮展示帖子详情
// @version      0.4
// @description  鼠标悬浮展示nodeseek帖子详情
// @author       hahahaha
// @namespace   *://*nodeseek.com/*
// @match       *://*nodeseek.com/*
// @grant        none
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    // 创建用于显示链接内容的元素
    var hoverBox = document.createElement('div');
    hoverBox.style.position = 'absolute';
    hoverBox.style.border = '1px solid black';
    hoverBox.style.background = 'white';
    hoverBox.style.padding = '10px';
    hoverBox.style.display = 'none';
    // 计算并设置固定宽度,这里假设取窗口宽度的 80%
    var fixedWidth = Math.min(0.8 * window.innerWidth, document.getElementById("nsk-body").offsetWidth - 100);
    hoverBox.style.width = fixedWidth + 'px';
    hoverBox.style.overflow = 'auto';
    document.body.appendChild(hoverBox);

    // 计算滚动条宽度
    function getScrollbarWidth() {
        var outer = document.createElement('div');
        outer.style.visibility = 'hidden';
        outer.style.width = '100px';
        outer.style.msOverflowStyle = 'scrollbar'; // needed for WinJS apps
        document.body.appendChild(outer);

        var widthNoScroll = outer.offsetWidth;
        // force scrollbars
        outer.style.overflow = 'scroll';

        // add innerdiv
        var inner = document.createElement('div');
        inner.style.width = '100%';
        outer.appendChild(inner);

        var widthWithScroll = inner.offsetWidth;

        // remove divs
        outer.parentNode.removeChild(outer);

        return widthNoScroll - widthWithScroll;
    }

    // 为所有 .post-title 下的 a 标签添加鼠标悬浮事件
    var links = document.querySelectorAll('.post-title a');
    links.forEach(function(link) {
        link.addEventListener('mouseover', function(event) {
            // 获取链接的 href
            var href = this.href;

            // 获取链接元素的边界信息
            var rect = this.getBoundingClientRect();

            // 发送 HTTP 请求到链接的 href
            fetch(href).then(function(response) {
                // 将响应的内容转换为文本
                return response.text();
            }).then(function(text) {
                // 创建一个新的 DOMParser
                var parser = new DOMParser();
                // 使用 DOMParser 解析响应的 HTML
                var doc = parser.parseFromString(text, 'text/html');
                // 获取 id 为 'nsk-body-left' 的元素的内容
                var content = doc.getElementById('nsk-body-left').innerHTML;
                // 更新 hoverBox 的内容
                hoverBox.innerHTML = content;

                // 移除多余的 pagination 组件
                removeExtraPagination(hoverBox);

                // 定义间距值
                const spacing = 20;
                // 计算可用高度
                var availableHeightBelow = window.innerHeight - rect.bottom - spacing;
                var availableHeightAbove = rect.top - spacing;

                if (availableHeightBelow > availableHeightAbove) {
                    // 向下展示
                    hoverBox.style.left = rect.left + 'px';
                    hoverBox.style.top = rect.bottom + window.scrollY + 'px';
                    // 确保悬浮框底部与浏览器窗口底部有间距
                    hoverBox.style.height = Math.min(availableHeightBelow, 500) + 'px';
                } else {
                    // 向上展示
                    hoverBox.style.left = rect.left + 'px';
                    hoverBox.style.top = rect.top + window.scrollY - Math.min(availableHeightAbove, 500) + 'px';
                    hoverBox.style.height = Math.min(availableHeightAbove, 500) + 'px';
                }

                hoverBox.style.display = 'block';

                // 禁用页面滚动但保留滚动条
                var scrollbarWidth = getScrollbarWidth();
                document.body.style.overflowY = 'hidden';
                document.body.style.paddingRight = scrollbarWidth + 'px';

                // 将悬浮框滚动到顶部
                hoverBox.scrollTop = 0;

                // 为悬浮框内的翻页链接添加点击事件监听器
                setupPaginationLinks(hoverBox, rect);
            }).catch(function(error) {
                // 如果发生错误,显示错误信息
                hoverBox.textContent = 'Error: ' + error;

                // 定义间距值
                const spacing = 20;
                // 计算可用高度
                var rect = event.target.getBoundingClientRect();
                var availableHeightBelow = window.innerHeight - rect.bottom - spacing;
                var availableHeightAbove = rect.top - spacing;

                if (availableHeightBelow > availableHeightAbove) {
                    // 向下展示
                    hoverBox.style.left = rect.left + 'px';
                    hoverBox.style.top = rect.bottom + window.scrollY + 'px';
                    // 确保悬浮框底部与浏览器窗口底部有间距
                    hoverBox.style.height = Math.min(availableHeightBelow, 500) + 'px';
                } else {
                    // 向上展示
                    hoverBox.style.left = rect.left + 'px';
                    hoverBox.style.top = rect.top + window.scrollY - Math.min(availableHeightAbove, 500) + 'px';
                    hoverBox.style.height = Math.min(availableHeightAbove, 500) + 'px';
                }

                hoverBox.style.display = 'block';

                // 禁用页面滚动但保留滚动条
                var scrollbarWidth = getScrollbarWidth();
                document.body.style.overflowY = 'hidden';
                document.body.style.paddingRight = scrollbarWidth + 'px';
            });
        });
    });

    // 点击 hoverBox 外部时隐藏 hoverBox
    document.addEventListener('click', function(event) {
        if (!hoverBox.contains(event.target)) {
            hoverBox.style.display = 'none';
            // 启用页面滚动
            document.body.style.overflowY = 'auto';
            document.body.style.paddingRight = '0px';
        }
    });

    // 鼠标进入悬浮框事件
    hoverBox.addEventListener('mouseenter', function() {
        document.body.style.overflowY = 'hidden';
    });

    // 鼠标离开悬浮框事件
    hoverBox.addEventListener('mouseleave', function() {
        document.body.style.overflowY = 'auto';
        document.body.style.paddingRight = '0px';
    });

    // 封装设置翻页链接事件监听器的函数
    function setupPaginationLinks(container, rect) {
        var paginationLinks = container.querySelectorAll('a');
        paginationLinks.forEach(function(paginationLink) {
            paginationLink.addEventListener('click', function(event) {
                console.log('Click event triggered on pagination link'); // 调试信息
                event.preventDefault();
                var newHref = this.href;
                fetch(newHref).then(function(response) {
                    return response.text();
                }).then(function(newText) {
                    var newParser = new DOMParser();
                    var newDoc = newParser.parseFromString(newText, 'text/html');
                    var newContent = newDoc.getElementById('nsk-body-left').innerHTML;
                    container.innerHTML = newContent;

                    // 移除多余的 pagination 组件
                    removeExtraPagination(container);

                    // 定义间距值
                    const spacing = 20;
                    // 重新计算高度和位置
                    var availableHeightBelow = window.innerHeight - rect.bottom - spacing;
                    var availableHeightAbove = rect.top - spacing;

                    if (availableHeightBelow > availableHeightAbove) {
                        // 向下展示
                        container.style.left = rect.left + 'px';
                        container.style.top = rect.bottom + window.scrollY + 'px';
                        // 确保悬浮框底部与浏览器窗口底部有间距
                        container.style.height = Math.min(availableHeightBelow, 500) + 'px';
                    } else {
                        // 向上展示
                        container.style.left = rect.left + 'px';
                        container.style.top = rect.top + window.scrollY - Math.min(availableHeightAbove, 500) + 'px';
                        container.style.height = Math.min(availableHeightAbove, 500) + 'px';
                    }

                    // 将悬浮框滚动到顶部
                    container.scrollTop = 0;
                    // 重新为新内容中的翻页链接添加点击事件监听器
                    setupPaginationLinks(container, rect);
                }).catch(function(error) {
                    container.textContent = 'Error: ' + error;
                });
            });
        });
    }

    // 移除多余的 pagination 组件
    function removeExtraPagination(container) {
        // 查找所有的翻页组件
        var paginationComponents = container.querySelectorAll('.nsk-pager');

        // 只保留最后一个翻页组件,移除其他的
        if (paginationComponents.length > 1) {
            for (var i = 0; i < paginationComponents.length - 1; i++) {
                paginationComponents[i].parentNode.removeChild(paginationComponents[i]);
            }
        }
    }
})();