jx filter ad

jx filter ad,不保证适用所有的jx页面,自用~

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         jx filter ad
// @namespace    http://tampermonkey.net/
// @version      3.0.0
// @description  jx filter ad,不保证适用所有的jx页面,自用~
// @author       ltxlong
// @match        *://*/*
// @grant        none
// @license      MIT
// @run-at       document-start
// ==/UserScript==

(function() {
    'use strict';

    let jx_filter_ad_open_flag = false;
    const the_jx_url_trait = [
        'v.qq.com',
        'iqiyi.com',
        'iq.com',
        'youku.com',
        'le.com',
        'tudou.com',
        'mgtv.com',
        'sohu.com',
        '1905.com',
        'bilibili.com',
        'pptv.com',
        'baofeng.com',
        'acfun.cn',
        'miguvideo.com',
        'yinyuetai.com',
        'fun.tv',
        'wasu.cn'
    ];

    const originUrl = window.location.origin;
    const originSearch = window.location.search;

    const hasMatchInSearch = the_jx_url_trait.some(trait => originSearch.includes(trait));
    if (hasMatchInSearch) {
        jx_filter_ad_open_flag = true;
    }

    if (!jx_filter_ad_open_flag) {
        return;
    }

    // 可以自定义需要去掉的id和class和其他定义的元素
    const adEleId = [];
    const adEleClass = [];
    const adEleOther = ['span[id]'];

    // 固定为PC ua
    Object.defineProperty(navigator, 'userAgent', {
        get: function () {
            return 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36';
        }
    });

    // Hook setInterval
    try {
        const originalSetInterval = window.setInterval;
        window.setInterval = function(callback, delay, ...args) {

            const callbackString = callback.toString();
            const filterPatterns = [
                '.appendChild(',
                '.insertBefore(',
                '.insertAfter(',
                '.append(',
                '.prepend(',
                '.after(',
                '.before(',
                '.appendTo(',
                '.prependTo(',
                '.html(',
                '.replaceWith(',
                '.wrap(',
                '.wrapAll(',
                '.wrapInner(',
            ];

            let isBlockFlag = false;
            if (typeof callbackString === 'string' && callbackString !== '[native code]') {
                for (const pattern of filterPatterns) {
                    if (callbackString.includes(pattern)) {
                        console.warn(`HOOK: Callback string contains filter pattern: "${pattern}"`);
                        isBlockFlag = true;
                        break;
                    }
                }
            }

            if (isBlockFlag) {
                return 0;
            }

            // --- 如果没有阻止,调用原始的 setInterval ---
            const intervalId = originalSetInterval.call(this, callback, delay, ...args);
            return intervalId;
        }
    } catch (error) {
        console.error('Error getting callback toString() or during string analysis:', error);
    }

    // 确保浏览器支持 Navigation API
    try {
        if ('navigation' in window) {

            window.navigation.addEventListener('navigate', (event) => {
                const destinationUrl = event.destination.url;

                const destinationOrigin = new URL(destinationUrl).origin;

                // Check if the destination origin is different from the current origin
                if (destinationOrigin !== originUrl) {
                    console.warn(`阻止了到非同源地址的跳转: ${destinationUrl}`);

                    // Prevent the default navigation behavior
                    // event.canIntercept must be true for preventDefault to work on this event type
                    if (event.canIntercept) {
                        event.preventDefault();;
                    } else {
                        console.log(`Navigation to ${destinationUrl} cannot be intercepted.`);
                        // Note: Some navigations like target="_blank" might not be interceptable this way
                    }


                } else {
                    console.log(`允许同源跳转: ${destinationUrl}`);
                    // Let the navigation proceed
                }

            });

            console.log(`当前页面源: ${window.location.origin}`);
            console.log('Navigation API 监听已启动...');

        } else {
            console.warn('当前浏览器不支持 Navigation API,请考虑使用 click/submit 监听作为替代。');
            // Fallback to click/submit method if necessary
        }

    } catch (e) {
        // Handle potential errors if the URL is invalid or cannot be parsed
        console.error('无法解析目标URL或发生错误:', e);
        // Decide whether to prevent or allow on error - usually allowing is safer
        // Let's assume allowing is the default if we can't verify
    }

    function removeTargetBlankDivs() {
        try {
            const blankTargetAnchors = document.querySelectorAll('a[target="_blank"]');
            if (blankTargetAnchors.length === 0) {
                //console.log("----------------No target='_blank' anchors found.");
                return;
            }

            blankTargetAnchors.forEach(anchor => {
                const parentDiv = anchor.closest('div');
                if (parentDiv) {
                    if (parentDiv.parentNode) {
                        //console.log("----------------Removing div: ", anchor.outerHTML);
                        parentDiv.remove();
                    }
                }
            });
        } catch (error) {
            console.error("----------------Error accessing or modifying content: ", error);
        }
    }

    function removeAdElement() {

        if (adEleId.length === 0 && adEleClass.length === 0 && adEleOther.length === 0) {
            return;
        }

        const selectors = [];
        if (adEleId.length > 0) {
            selectors.push(...adEleId.map(id => `#${id}`));
        }
        if (adEleClass.length > 0) {
            selectors.push(...adEleClass.map(className => `.${className}`));
        }
        if (adEleOther.length > 0) {
            selectors.push(...adEleOther.map(otherEle => `${otherEle}`));
        }
        if (selectors.length === 0) {
            return;
        }

        const combinedSelector = selectors.join(', ');
        try {
            const elementsToRemove = document.querySelectorAll(combinedSelector);

            elementsToRemove.forEach(element => {
                // 使用 element.remove() 是现代且推荐的删除元素方法
                // 兼容性:IE(Edge 除外)不支持,但现代浏览器都支持
                if (element && typeof element.remove === 'function') {
                    element.remove();
                    // console.log("已删除元素:", element); // 可选:记录删除的元素
                } else if (element && element.parentNode) {
                    // 兼容旧浏览器,通过父节点删除
                    element.parentNode.removeChild(element);
                    // console.log("已删除元素 (旧方法):", element); // 可选:记录删除的元素
                }
            });
        } catch(error) {
            console.error("删除元素时发生错误:", error);
        }
    }

    removeTargetBlankDivs();
    removeAdElement();

    // 考虑网速慢和卡顿的情况
    setTimeout(() => { removeTargetBlankDivs(); removeAdElement(); }, 1000)
    setTimeout(() => { removeTargetBlankDivs(); removeAdElement(); }, 2000)
    setTimeout(() => { removeTargetBlankDivs(); removeAdElement(); }, 3000)
    setTimeout(() => { removeTargetBlankDivs(); removeAdElement(); }, 5000)
    setTimeout(() => { removeTargetBlankDivs(); removeAdElement(); }, 10000)
    setTimeout(() => { removeTargetBlankDivs(); removeAdElement(); }, 20000)
    setTimeout(() => { removeTargetBlankDivs(); removeAdElement(); }, 30000)

    try {
        window.addEventListener('load', () => {
            removeTargetBlankDivs();
            removeAdElement();
        })
    } catch (error) {
        console.error("监听页面load发生错误:", error);
    }

})();