屏蔽博客园背景动态线条

1. 问题描述

由于博客园允许用户添加含js的html代码来装饰自己的博客界面,这导致很多人跟风地给自己博客添加背景动态线条live2D等,其中动态背景线条如下图所示:
动态线条
它不停地随机生成线条,并漂浮移动,一段时间后消失。但如果鼠标靠近,就会吸附到鼠标上,且不会消失

当我们阅读文章时,如果鼠标停留在页面上,那么鼠标位置就会不停地吸附线条,然后越来越多(达到最大数量时,貌似就不生成了),且不停地计算旋转变换,这会占用一部分的CPU资源,如果其他程序也开得挺多的话,可能导致CPU风扇狂转。
这么没用的东西,既占CPU还分散注意力,应该统统禁掉!

2. 动态线条js加载过程

当我们打开一个博客园用户主页或某篇文章时,网址格式如下:
https://www.cnblogs.com/oldwangcy/p/11371550.html
html 会请求下载blog-common.min.js,在这个js文件中定义了一个函数loadBlogNews,然后html文件内部script会稍后调用 loadBlogNews()
loadBlogNews 的定义如下:

function loadBlogNews() {
    $.ajax({
        url: getAjaxBaseUrl() + "news.aspx",
        type: "get",
        dataType: "text",
        success: function(n) {
            if (n)
                if (n.indexOf("<script") < n.indexOf("<script>getFollowStatus")) {
                    if (n.indexOf("cdn.jsdelivr.net/gh/BNDong/Cnblogs-Theme-SimpleMemory") >= 0) {
                        var t = n.match(/GhUserName *: *['"](\w+)['"]/);
                        (t === null || t[1].toUpperCase() === "BNDong".toUpperCase()) && (n = n.replace(/(GhVersions *: *["'])v1\.([0-1]\.\d+|2\.[0-5].*?),*/g, "$1v1.2.6").replace(/(Cnblogs-Theme-SimpleMemory@)v1\.([0-1]\.\d+|2\.[0-5])/gi, "$1v1.2.6"))
                    }
                    $.getScript(location.protocol + "//common.cnblogs.com/script/jquery.writeCapture-min.js", function() {
                        $("#sidebar_news").writeCapture().html(n).show()
                    })
                } else
                    n.indexOf("错误提示:发生了异常") < 0 && $("#sidebar_news").html(n).show()
        }
    })
}

可以看到,此函数将使用 $.ajax 下载了一个名为 new.aspx 的文件,然后这一句$("#sidebar_news").writeCapture().html(n).show()执行了此文件的内容。
可以在浏览器开发者工具-network下找到此文件。文件内容大概如下(不同的人可能不一样):

<!--done-->
<h3 class="catListTitle">公告</h3>
<div id="blog-news">
    <div style = "display:none;">动态线条</div>
    <script>
    !function(){
        function n(n,e,t){
            return n.getAttribute(e)||t
        }
        function e(n){
            return document.getElementsByTagName(n)
        }
        function t(){
            var t=e("script"),o=t.length,i=t[o-1];
            return{
                l:o,z:n(i,"zIndex",-1),o:n(i,"opacity",.5),c:n(i,"color","0,0,0"),n:n(i,"count",99)
            }
        }
        function o(){
            a=m.width=window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth,
            c=m.height=window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight
        }
        function i(){
            r.clearRect(0,0,a,c);
            var n,e,t,o,m,l;
            s.forEach(function(i,x){
                for(i.x+=i.xa,i.y+=i.ya,i.xa*=i.x>a||i.x<0?-1:1,i.ya*=i.y>c||i.y<0?-1:1,r.fillRect(i.x-.5,i.y-.5,1,1),e=x+1;e<u.length;e++)n=u[e],
                null!==n.x&&null!==n.y&&(o=i.x-n.x,m=i.y-n.y,
                l=o*o+m*m,l<n.max&&(n===y&&l>=n.max/2&&(i.x-=.03*o,i.y-=.03*m),
                t=(n.max-l)/n.max,r.beginPath(),r.lineWidth=t/2,r.strokeStyle="rgba("+d.c+","+(t+.2)+")",r.moveTo(i.x,i.y),r.lineTo(n.x,n.y),r.stroke()))
            })
            ,
            x(i)
        }
        var a,c,u,m=document.createElement("canvas"),
        d=t(),l="c_n"+d.l,r=m.getContext("2d"),
        x=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||
        function(n){
            window.setTimeout(n,1e3/45)
        },
        w=Math.random,y={
        x:null,y:null,max:2e4};
        m.id=l,m.style.cssText="position:fixed;top:0;left:0;z-index:"+d.z+";opacity:"+d.o,e("body")[0].appendChild(m),o(),window.onresize=o,
        window.onmousemove=function(n){
            n=n||window.event,y.x=n.clientX,y.y=n.clientY
        },
        window.onmouseout=function(){
            y.x=null,y.y=null
        };
        for(var s=[],f=0;d.n>f;f++){
            var h=w()*a,g=w()*c,v=2*w()-1,p=2*w()-1;
            s.push({
            x:h,y:g,xa:v,ya:p,max:6e3})
        }
        u=s.concat([y]),
        setTimeout(function(){
        i()},
        100)
    }
    ();
    </script>
    <div style = "display:none;"> 动态线条end</div>
    <div id="profile_block">
        昵称:
        <a href="https://home.cnblogs.com/u/baby-lily/">Baby-Lily</a><br />
        园龄:
        <a href="https://home.cnblogs.com/u/baby-lily/" title="入园时间:2019-03-19">
        1年5个月
        </a><br />
        粉丝:
        <a href="https://home.cnblogs.com/u/baby-lily/followers/">
        24
        </a><br />
        关注:
        <a href="https://home.cnblogs.com/u/baby-lily/followees/">
        9
        </a>
        <div id="p_b_follow"></div>
        <script>
            getFollowStatus('73594955-3c31-45bb-d67b-08d6ab35ac30');
        </script>
    </div>
</div>

显然,用户自定义的脚本就放在这里。

3. 解决方案

既然已经知道了是怎样加载的,那么我们可以写一个脚本,交给TamperMonkey这个插件去执行。
大致思路是这样

  • 检测loadBlogNews是否已成功定义,如果是,那么重写一个函数覆盖掉。
  • 重写的函数与原来的基本一致,但是在 new.aspx 被执行前,用正则把用户自定义的脚本替换成空字符串。

代码如下:
在 油猴中新建脚本,粘贴如下代码,保存。

// ==UserScript==
// @name         prevent dynamic lines of cnblogs 屏蔽博客园动态线条
// @namespace    https://blog.csdn.net/qq1337715208/article/details/108289826
// @version      0.1
// @description  将博客园背景中用户添加的脚本代码替换掉
// @author       jin
// @match        *://*.cnblogs.com/*
// @grant        none
// @require      https://common.cnblogs.com/scripts/jquery-2.2.0.min.js
// ==/UserScript==

(function() {
    'use strict';
    // 最多检测50次,找不到 loadBlogNews 就放弃
    let maxCheckNum = 50;
    function check_f(){
        try {
            if (typeof(loadBlogNews) == "function") {
                return true;
            }
        } catch(e) {
            return false;
        }
        return false;
    }
    function tryStopIt(){
        if (!check_f()){
            if (maxCheckNum > 0){
                maxCheckNum -= 1
                setTimeout(tryStopIt, 100); //没找到就每隔0.1秒重试
            } else {// 尝试50次后还没有找到,就放弃
                 console.log("未找到,替换失败。");
            }
            return;
        } // end if (!check_f)
        loadBlogNews = function () {
            $.ajax({
                url: getAjaxBaseUrl() + "news.aspx",
                type: "get",
                dataType: "text",
                success: function(n) {
                    if (n)
                        if (n.indexOf("<script") < n.indexOf("<script>getFollowStatus")) {
                            if (n.indexOf("cdn.jsdelivr.net/gh/BNDong/Cnblogs-Theme-SimpleMemory") >= 0) {
                                var t = n.match(/GhUserName *: *['"](\w+)['"]/);
                                (t === null || t[1].toUpperCase() === "BNDong".toUpperCase()) && (n = n.replace(/(GhVersions *: *["'])v1\.([0-1]\.\d+|2\.[0-5].*?),*/g, "$1v1.2.6").replace(/(Cnblogs-Theme-SimpleMemory@)v1\.([0-1]\.\d+|2\.[0-5])/gi, "$1v1.2.6"))
                            }
                            $.getScript(location.protocol + "//common.cnblogs.com/script/jquery.writeCapture-min.js", function() {
                                
                                
                                let reg1 = new RegExp("[\\r\\n]", "g");
                                let reg2 = new RegExp("<script.*?>.*?window\\.requestAnimationFrame.*?</script>","g");
                                let filted_content = n.replace(reg1," ");
                                filted_content = filted_content.replace(reg2, " ");
                                
                                let reg3 = new RegExp("<script.+?src=[\"'](.+?)[\"'].*?>.*?</script>","g");
                                
                                filted_content = filted_content.replace(reg3, function(subtxt, cat1, pian, txt){
                                    let bad = false;
                                    $.ajax({
                                        url:cat1,
                                        type:"get",
                                        dataType:"text",
                                        async:false,
                                        success:function(resp){
                                            resp = resp.replace(reg1, " ");
                                            let reg4 = new RegExp("<script.*?>.*?window\\.requestAnimationFrame.*?</script>","g");
                                            //let reg5 = new RegExp("<script.+?src=[\"'].+?[\"'].*?>.*?</script>","g");
                                            if (reg4.exec(resp)) {
                                                 bad = true;
                                            }
                                        }
                                    });
                                    if (bad) {
                                        return " ";
                                    }
                                    return subtxt;
                                });
                                ///
                                console.alert("debug : " + filted_content);
                                $("#sidebar_news").writeCapture().html(filted_content).show();
                            })
                        } else
                            n.indexOf("错误提示:发生了异常") < 0 && $("#sidebar_news").html(n).show();
                }
            }) // end $.ajax
        } //end loadBlogNews
        console.log("成功地替换了 loadBlogNews");
        return;
    }
    tryStopIt();
})();

4. 效果测试

随便找了个有动态线条的博客:https://www.cnblogs.com/oldwangcy/p/11371550.html

关闭脚本时:

在这里插入图片描述

打开脚本时:

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值