百度搜索 - 优化

1、屏蔽百度推广 2、关闭百度广告联盟信息收集 3、绑定快捷键 4、布局调整 5、居中单列(可选) 6、居中双列(可选)

当前为 2019-02-05 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         百度搜索 - 优化
// @namespace    http://tampermonkey.net/
// @home-url     https://greasyfork.org/zh-CN/scripts/31642
// @description  1、屏蔽百度推广 2、关闭百度广告联盟信息收集 3、绑定快捷键 4、布局调整 5、居中单列(可选) 6、居中双列(可选)
// @version      4.1.7
// @author       浮生未歇
// @run-at       document-start
// @include      https://www.baidu.com/
// @include      https://www.baidu.com/s?*
// @incluce      https://www.baidu.com/#*
// @include      https://www.baidu.com/baidu?*
// @exclude      https://www.baidu.com/home*
// @exclude      https://www.baidu.com/sf*
// @exclude      https://www.baidu.com/search*
// @exclude      https://www.baidu.com/link*
// @exclude      https://www.baidu.com/s*tn=news*
// @resource     baiduIndexStyle   https://cdn.jsdelivr.net/gh/sinlin/[email protected]/2018-10-30/indexStyle.css
// @resource     baiduCommonStyle  https://cdn.jsdelivr.net/gh/sinlin/[email protected]/2018-10-30/commonStyle.css
// @resource     baiduMenu         https://cdn.jsdelivr.net/gh/sinlin/[email protected]/2018-10-30/menu.css
// @resource     baiduOne          https://cdn.jsdelivr.net/gh/sinlin/[email protected]/2018-10-30/one.css
// @resource     baiduTwo          https://cdn.jsdelivr.net/gh/sinlin/[email protected]/2018-10-30/two.css
// @resource     baiduThree        https://cdn.jsdelivr.net/gh/sinlin/[email protected]/2018-10-30/three.css
// @connect      *
// @grant        GM_addStyle
// @grant        GM_getResourceText
// @grant        GM_getResourceURL
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_deleteValue
// @grant        GM_xmlhttpRequest
// ==/UserScript==


(() => {
    //初始化配置
    const Config = {
        //是否调试
        IS_DEBUG: false,
        //壁纸地址
        BACKGROUND_URL: "https://ss2.bdstatic.com/lfoZeXSm1A5BphGlnYG/skin/37.jpg",
        //菜单按钮 ID
        MENU_BUTTON_ID: "CustomMenu",
        //菜单功能页 ID
        MENU_PAGE_ID: "menulist",
        //菜单保存按钮 ID
        MENU_SAVA_ID: "menusava",
        //功能配置
        OPTIONS: [
            //页面布局:1:普通页面,2:单列居中,3:双列居中,4:三列居中
            { name: "SELECT_PAGE", value: 1 },
            //重定向
            { name: "SWITCH_IS_REDIRECT", value: false },
            //加载下一页
            { name: "SWITCH_IS_LOADPAGE", value: false },
            //固定侧边栏
            { name: "SWITCH_IS_FIXEDSILDER", value: false },
            //加载背景
            { name: "SWITCH_IS_BACKGOUND", value: false }
        ],
        //百度样式
        BAIDU_STYLES: [
            {
                //百度首页
                INDEX: GM_getResourceText("baiduIndexStyle"),
                //普通页
                COMMON: GM_getResourceText("baiduCommonStyle"),
                //菜单
                MENU: GM_getResourceText("baiduMenu"),
                //单页
                ONE: GM_getResourceText("baiduOne"),
                //双页
                TWO: GM_getResourceText("baiduTwo"),
                //三页
                THREE: GM_getResourceText("baiduThree")
            }
        ],
        //过滤功能 ,不能设置 G(已被 Google搜索 占用)
        FILTERS: [
            {
                name: "B",
                value: "-baijiahao"
            },
            {
                name: "C",
                value: "site:bbs.csdn.net"
            },
            {
                name: "T",
                value: "site:tieba.baidu.com"
            },
            {
                name: "J",
                value: "site:juejin.im"
            },
            {
                name: "S",
                value: "site:segmentfault.com"
            },
            {
                name: "V",
                value: "site:v2ex.com"
            },
            {
                name: "Z",
                value: "site:zhihu.com"
            }
        ]
    };
    //打包
    const BaiduConfig = { window, document, location, Config };
    //Baidu
    const Baidu = (({ window, document, location, Config }) => {
        //创建空对象
        const Baidu = Object.create(null);
        const Options = Object.create(null);
        //引用
        const BAIDU_STYLES = Config.BAIDU_STYLES[0];
        const BAIDU_OPTIONS = Config.OPTIONS;
        //菜单功能页选项
        Options.SELECT_PAGE = BAIDU_OPTIONS[0];
        Options.SWITCH_IS_REDIRECT = BAIDU_OPTIONS[1];
        Options.SWITCH_IS_LOADPAGE = BAIDU_OPTIONS[2];
        Options.SWITCH_IS_FIXEDSILDER = BAIDU_OPTIONS[3];
        Options.SWITCH_IS_BACKGOUND = BAIDU_OPTIONS[4];
        /**
         * 实现 ready 功能, 文档完成后即执行
         * 举例 : Baidu.ready = function(){}
         */
        Reflect.defineProperty(Baidu, "ready", {
            set: fn => {
                if (document.readyState === "complete") {
                    fn();
                }
                else if (!!document.addEventListener) {
                    document.addEventListener("DOMContentLoaded", () => {
                        fn();
                    }, true);
                }
                else {
                    throw new Error("Baidu.ready can't use");
                }
            }
        });
        /**
         * 延时执行
         */
        Baidu.delayRun = (callback, count = 0) => {
            if (count === 0) {
                window.requestAnimationFrame(() => {
                    callback();
                });
            }
            else {
                window.requestAnimationFrame(() => {
                    Baidu.delayRun(callback, --count);
                });
            }
        };
        /**
         * DOM缓存
         */
        class DomCache {
            constructor() {
                this.cache = {};
            }
            hasDomCache(name) {
                return this.cache.hasOwnProperty(name) && !!this.cache[name]
                    ? true
                    : false;
            }
            deleteCache() {
                this.cache = {};
            }
            getElementById(name) {
                if (!this.hasDomCache(name)) {
                    this.cache[name] = document.getElementById(name);
                }
                return this.cache[name];
            }
        }
        Baidu.DOM = new DomCache();
        /**
         * GM数据类
         * @class GM
         */
        let GM = class {
            static getValue(selection) {
                try {
                    return GM_getValue(selection.name, selection.value);
                }
                catch (error) {
                    throw new Error(error);
                }
            }
            static setValue(name, value) {
                try {
                    GM_setValue(name, value);
                }
                catch (error) {
                    throw new Error(error);
                }
            }
            static addStyle(style) {
                try {
                    GM_addStyle(style);
                }
                catch (error) {
                    throw new Error(error);
                }
            }
            static xmlhttpRequest(object) {
                try {
                    GM_xmlhttpRequest(object);
                }
                catch (error) {
                    throw new Error(error);
                }
            }
        };
        /**
         * 减少执行
         */
        class ReduceExecute {
            constructor() {
                this.isNormalExecuteState = true;
            }
            /**
             * 是否正常执行
             */
            isNormalExecute() {
                return this.isNormalExecuteState;
            }
            /**
             * 停止正常执行
             */
            stopNormalExecute() {
                this.isNormalExecuteState = false;
                return this;
            }
            /**
             * 恢复正常执行
             * @param time 时间片 1 = 16.7ms
             */
            regainNormalExecute(time) {
                Baidu.delayRun(() => {
                    this.isNormalExecuteState = true;
                }, time);
            }
        }
        /**
         * 缓存类
         * 用于对数据的缓存
         * @class Cache
         *
         */
        class Cache {
            constructor() {
                this.cache = "";
            }
            /**
             * 删除缓存
             */
            delCache() {
                this.cache = "";
            }
            /**
             * 添加缓存
             * @param Content {string} 缓存内容
             */
            addCache(Content) {
                this.cache += Content;
            }
            /**
             * 获取缓存内容
             */
            getCache() {
                return this.cache;
            }
        }
        /**
         * 样式
         * @class Style
         * @extends Cache
         *
         */
        class Style {
            constructor() {
                this.Cache = new Cache();
                this.GM = GM;
            }
            /**
             * 导入样式
             * @method importStyle
             *
             */
            importStyle() {
                let styles = this.Cache.getCache();
                try {
                    this.GM.addStyle(styles);
                }
                catch (error) {
                    throw new Error("can't import styles:" + error);
                }
            }
            /**
             * 将样式加入缓存
             * @param {stirng} style 样式
             * @return {Style} this 该实例
             */
            add(style) {
                this.Cache.addCache(style);
                return this;
            }
            /**
             * 结束
             * 开始将缓存样式导入,并清空缓存
             */
            end() {
                this.importStyle();
                this.Cache.delCache();
            }
        }
        /**
         * 函数执行器 - 组合执行
         */
        class Commond {
            constructor() {
                this.commondList = [];
            }
            /**
             * 添加数组缓存中
             * @param {object} command 对象实例
             */
            add(command) {
                this.commondList.push(command);
            }
            /**
             * 执行数值缓存中的实例
             * 如果执行实例返回 true 停止执行。
             */
            execute(isSplitExecute = false) {
                for (let i = 0, command; (command = this.commondList[i++]);) {
                    command.execute();
                }
            }
        }
        /**
         * 检测功能 - 避免代码多次执行
         * @class AvoidMulExecute
         */
        class AvoidMulExecute {
            constructor() {
                //标志名称
                this.signName = "isRun";
            }
            /**
             * 增加标志位
             */
            setSign() {
                let signName = this.signName;
                let container = document.getElementById("content_left");
                container.setAttribute(signName, true);
            }
            /**
             * 判断是否存在标志位
             */
            hasSign() {
                let signName = this.signName;
                let container = document.getElementById("content_left");
                return !!container.hasAttribute(signName);
            }
        }
        /**
         * 重定向搜索地址
         * @class RedirectURL
         */
        class RedirectURL {
            constructor() {
                this.end = "&baidu";
            }
            /**
             * 重定向地址
             * @method redirectURL
             */
            redirectURL() {
                let end = this.end;
                let URL = location.href;
                if (!URL.endsWith(end)) {
                    //判断是否存在步进值,没有使用默认值 20
                    if (!URL.includes("&rn=")) {
                        URL += "&rn=20";
                    }
                    //拼接地址
                    URL += end;
                    //去除推广链接
                    URL = URL.replace(/\&tn=\S+\&/, "&");
                    //跳转
                    location.href = URL;
                }
            }
            /**
             * 初始化
             * @method init
             */
            init() {
                this.redirectURL();
            }
            /**
             * 启动
             * @method execute
             */
            execute() {
                this.init();
            }
        }
        /**
         * 首页样式
         * @class IMportIndexStyle
         */
        class ImportIndexStyle {
            constructor() {
                //实例化
                this.Style = new Style();
            }
            /**
             * 导入样式
             * @method import
             */
            import() {
                let style = this.Style;
                style.add(BAIDU_STYLES.INDEX);
                style.end();
            }
            /**
             * 初始化
             * @method init
             */
            init() {
                this.import();
            }
            /**
             * 执行
             * @method execute
             */
            execute() {
                this.init();
            }
        }
        /**
         * 导入普通结果页样式
         * @class ImportCommonStyle
         */
        class ImportCommonStyle {
            constructor() {
                //实例化
                this.Style = new Style();
                this.GM = GM;
                //功能选项
                this.Options = Options;
                //背景地址
                this.backgoundURL = Config.BACKGROUND_URL;
                //布局类型
                this.layoutType = Number(this.GM.getValue(this.Options.SELECT_PAGE));
                //是否导入背景
                this.isImportBackground = Boolean(this.GM.getValue(this.Options.SWITCH_IS_BACKGOUND));
                //是否导入样式
                this.isImportFixedSlider = Boolean(this.GM.getValue(this.Options.SWITCH_IS_FIXEDSILDER));
            }
            /**
             * 样式 - 背景
             * @method styleForBackground
             * @returns {string} 样式
             */
            styleForBackground() {
                let defaultURL = this.backgoundURL;
                if (this.isImportBackground) {
                    return `body{background-color:transparent!important}body:after{content:"";position:fixed;top:0;bottom:0;left:0;right:0;background-image:url(${defaultURL})!important;background-size:cover!important;z-index:-1}#head{background-color:hsla(0, 0%, 100%, 0.65)!important;border-bottom-color:hsla(0, 0%, 52%, 0.3)!important}#content_left .c-container,#rs{border:none!important;background: hsla(0, 0%, 100%, 0.85)!important}#form>.s_ipt_wr.bg{background:#fff!important}#u>a{color: hsl(216, 80%, 63%)!important}#u>a:after{background:transparent!important;border:1px solid!important;}`;
                }
                else {
                    return "";
                }
            }
            /**
             * 样式 - 固定侧边栏
             * @method styleForFixedSilder
             * @returns {string} 样式
             */
            styleForFixedSilder() {
                if (this.isImportFixedSlider) {
                    return "#s_tab{left:0!important;opacity:1!important;}";
                }
                else {
                    return "";
                }
            }
            /**
             * 样式  - 页面布局
             * @method styleForPageLayout
             * @returns {string} 样式
             */
            styleForPageLayout() {
                let layoutType = this.layoutType;
                switch (layoutType) {
                    case 1:
                        return "";
                    case 2:
                        return BAIDU_STYLES.ONE;
                    case 3:
                        return BAIDU_STYLES.TWO;
                    case 4:
                        return BAIDU_STYLES.THREE;
                }
            }
            /**
             * 样式 - 菜单
             * @method styleForMenu
             * @returns {string} 样式
             */
            styleForMenu() {
                return BAIDU_STYLES.MENU;
            }
            /**
             * 样式 - 结果页
             * @method styleForCommand
             * @returns {string} 样式
             */
            styleForCommand() {
                return BAIDU_STYLES.COMMON;
            }
            /**
             * 导入样式
             * @method import
             */
            import() {
                let style = this.Style;
                style.add(this.styleForCommand());
                style.add(this.styleForMenu());
                style.add(this.styleForPageLayout());
                style.add(this.styleForFixedSilder());
                style.add(this.styleForBackground());
                style.end();
            }
            /**
             * 初始化
             * @method init
             */
            init() {
                this.import();
            }
            /**
             * 执行
             * @method execute
             */
            execute() {
                this.init();
            }
        }
        /**
         * 菜单功能页
         * @class MenuItemsOptions
         * @extends MenuCommand
         */
        class MenuItemsOptions {
            constructor() {
                this.GM = GM;
                this.Options = Options;
                this.layoutTagName = "baidupage";
                this.switchTagName = "baiduswitch";
                //页面布局类型
                this.layoutType = Number(this.GM.getValue(this.Options.SELECT_PAGE));
            }
            /**
             * 获得 HTML - 页面布局选项
             * @param content 显示的内容
             * @param layoutType 页面布局类型
             */
            getContentPageSelect(content, layoutType) {
                let checked = this.layoutType === layoutType ? "checked" : "";
                return `<li><input type="radio" name="${this.layoutTagName}" value="${layoutType}" ${checked}>${content}</li>`;
            }
            /**
             * 获得 HTML - 功能选项选项
             * @param content 显示的内容
             * @param selection 功能配置
             */
            getContentFunSelect(content, selection) {
                let switchName = selection.name;
                let checked = Boolean(this.GM.getValue(selection))
                    ? "checked"
                    : "";
                return `<li><input type="checkbox" name="${this.switchTagName}" value="${switchName}" ${checked}>${content}</li>`;
            }
            /**
             * 获得 HTML - 保存
             * @param content 显示的内容
             */
            getContentSava(content) {
                let idName = Config.MENU_SAVA_ID;
                return `<input id='${idName}' type='button' style='display:block;width:100%' value='${content}'>`;
            }
            //获取整体 HTML
            getContent() {
                let content = "";
                content += "<ol>页面选择";
                content += this.getContentPageSelect("普通页面", 1);
                content += this.getContentPageSelect("单页居中", 2);
                content += this.getContentPageSelect("双页居中", 3);
                content += this.getContentPageSelect("三页居中", 4);
                content += "</ol>";
                content += "<ol>功能选择";
                content += this.getContentFunSelect("使用重定向", this.Options.SWITCH_IS_REDIRECT);
                content += this.getContentFunSelect("自动下一页", this.Options.SWITCH_IS_LOADPAGE);
                content += this.getContentFunSelect("固定侧边栏", this.Options.SWITCH_IS_FIXEDSILDER);
                content += this.getContentFunSelect("加载背景", this.Options.SWITCH_IS_BACKGOUND);
                content += "</ol>";
                content += this.getContentSava("保存");
                return content;
            }
            /**
             * 绑定保存事件
             */
            bindSavaClick() {
                let sava = document.getElementById(Config.MENU_SAVA_ID);
                sava.onclick = event => {
                    let e = event || window.event;
                    //页面布局选项
                    let radios = document.getElementsByName(this.layoutTagName);
                    for (let i = 0, radio; (radio = radios[i++]);) {
                        if (radio.checked) {
                            let name = Options.SELECT_PAGE.name;
                            let value = radio.value;
                            this.GM.setValue(name, value);
                            break;
                        }
                    }
                    //功能选项
                    let checkboxs = document.getElementsByName(this.switchTagName);
                    for (let i = 0, checkbox; (checkbox = checkboxs[i++]);) {
                        let name = checkbox.value;
                        if (checkbox.checked) {
                            this.GM.setValue(name, true);
                        }
                        else {
                            this.GM.setValue(name, false);
                        }
                    }
                    e.stopPropagation();
                    location.href = location.href;
                };
            }
            /**
             * 插入节点
             */
            insertNode() {
                let container = document.getElementById("u"), content = this.getContent(), div = document.createElement("div");
                div.id = Config.MENU_PAGE_ID;
                div.style.display = "none";
                div.innerHTML = `<div>${content}</div>`;
                container.insertBefore(div, container.firstChild);
            }
            /**
             * 初始化
             */
            init() {
                let isExecute = document.getElementById(Config.MENU_PAGE_ID);
                if (!isExecute) {
                    this.insertNode();
                    //异步执行绑定事件
                    Baidu.delayRun(() => {
                        this.bindSavaClick();
                    }, 10);
                }
            }
            /**
             * 执行
             */
            execute() {
                Baidu.ready = () => {
                    try {
                        this.init();
                    }
                    catch (e) {
                        throw new Error(e);
                    }
                };
            }
        }
        /**
         * 菜单按钮
         * @class MenuButton
         * @extends MenuCommand
         */
        class MenuButton {
            constructor() {
                this.MenuItemsOptions = new MenuItemsOptions();
            }
            /**
             * 修复未登录按钮错位问题
             */
            fixedNoLoginButtonPosition() {
                let container = document.getElementById("u");
                let isExecute = container.querySelector("#u>a[name='tj_login']");
                if (isExecute) {
                    let selector = document.getElementById(Config.MENU_BUTTON_ID);
                    selector.setAttribute("style", "top:-4px!important");
                }
            }
            /**
             * 第二次单击隐藏
             */
            bindClickHide() {
                document.onclick = event => {
                    let e = event || window.event;
                    let container = document.getElementById("container");
                    let items = document.getElementById(Config.MENU_PAGE_ID);
                    let isScreenClick = e.target
                        ? e.target == container
                        : e.srcElement == container;
                    if (isScreenClick) {
                        items.style.display = "none";
                    }
                };
            }
            /**
             * 单击打开功能选项页
             */
            bindClick() {
                let container = document.getElementById(Config.MENU_BUTTON_ID);
                container.onclick = event => {
                    let e = event || window.event;
                    let items = document.getElementById(Config.MENU_PAGE_ID);
                    let style = items.style;
                    let isShow = style.display === "block";
                    if (isShow) {
                        style.display = "none";
                    }
                    else {
                        style.display = "block";
                    }
                    //阻止冒泡
                    e.stopPropagation();
                };
            }
            /**
             * 插入节点
             */
            insertNode() {
                let container = document.getElementById("u");
                let div = document.createElement("a");
                div.id = Config.MENU_BUTTON_ID;
                div.innerHTML = "自定义";
                container.insertBefore(div, container.firstChild);
            }
            /**
             * 初始化
             */
            init() {
                let isExecute = document.getElementById(Config.MENU_BUTTON_ID);
                if (!isExecute) {
                    this.insertNode();
                    //异步绑定事件
                    Baidu.delayRun(() => {
                        this.bindClick();
                        this.bindClickHide();
                    }, 10);
                }
            }
            /**
             * 执行
             */
            execute() {
                Baidu.ready = () => {
                    Promise.resolve().then(() => {
                        this.init();
                    });
                };
                //执行菜单功能面板
                Promise.resolve().then(() => {
                    this.MenuItemsOptions.execute();
                });
            }
        }
        /**
         * 多页布局
         * @class MUlPageLayout
         */
        class MulPageLayout {
            constructor() {
                this.GM = GM;
                this.DOM = Baidu.DOM;
                this.container = null;
                this.lists = null;
                //多列布局值集合
                this.layoutTypes = [3, 4];
                //当前布局类型
                this.layoutType = Number(this.GM.getValue(Options.SELECT_PAGE));
                //根据 类名 模拟高度
                this.VIRTUAL_HEIGHTS_BY_CLASSNAE = [
                    { name: ".c-container>.op-b2b-straight", value: 420 },
                    { name: ".c-container>.c-offset", value: 320 },
                    { name: ".c-container>.c-border", value: 270 },
                    {
                        name: ".c-container>.op-tieba-general-lookmore",
                        value: 260
                    },
                    {
                        name: ".c-container>.op-img-address-desktop-cont",
                        value: 210
                    },
                    { name: ".c-container>.c-gap-top-small", value: 130 }
                ];
                //根据 srcid 属性值 模拟高度
                this.VIRTUAL_HEIGHTS_BY_SRCID = [
                    { name: 1599, value: 128 },
                    { name: 1508, value: 170 },
                    { name: 1527, value: 170 },
                    { name: 1528, value: 220 },
                    { name: 1529, value: 220 },
                    { name: 1537, value: 510 },
                    { name: 1539, value: 280 },
                    { name: 1545, value: 230 },
                    { name: 1547, value: 230 },
                    { name: 4515, value: 540 },
                    { name: 5103, value: 400 },
                    { name: 8041, value: 260 },
                    { name: 8191, value: 200 },
                    { name: 10, value: 260 },
                    { name: 13, value: 220 },
                    { name: 19, value: 200 }
                ];
            }
            /**
             * 是否为多列布局
             * @return {boolean}
             */
            isMulLayout() {
                let layoutType = this.layoutType;
                let layoutTypes = this.layoutTypes;
                return layoutTypes.includes(layoutType);
            }
            /**
             * 初始化
             */
            resetDOM() {
                this.container = null;
                this.lists = null;
            }
            /**
             * 获取 #content_left 节点
             */
            getDomForContainer() {
                if (!this.container) {
                    this.container = this.DOM.getElementById("content_left");
                }
                return this.container;
            }
            /**
             * 获取 list 节点
             */
            getDomForLists() {
                if (!this.lists) {
                    let container = this.getDomForContainer();
                    this.lists = container.getElementsByClassName("list");
                }
                return this.lists;
            }
            //获取list高度合集
            getListsHeight() {
                let lists = this.getDomForLists();
                let heights = [];
                for (let i = 0, list; (list = lists[i++]);) {
                    heights.push(list.clientHeight);
                }
                return heights;
            }
            /**
             * 模拟高度
             * 防止获取真实高度导致性能问题
             * @param item
             */
            getItemVirtualHeight(item) {
                // 获取虚拟高度合集
                let VIRTUAL_DATAS = this.VIRTUAL_HEIGHTS_BY_SRCID;
                //默认高度
                let height = 122;
                //匹配 srcid 正则
                let reg = /srcid="\d+"/;
                //获取srcid
                let srcid = Number(/\d+/.exec(reg.exec(item.outerHTML)));
                //根据srcid值获取虚拟高度
                for (let i = 0, data; (data = VIRTUAL_DATAS[i++]);) {
                    //大于 10000 直接赋予新高度
                    if (srcid > 10000) {
                        height = 310;
                        break;
                    }
                    else if (srcid === data["name"]) {
                        height = data["value"];
                        break;
                    }
                }
                return height;
            }
            /**
             * 01 - 添加内容到lists
             * 使用 DOM 到 DOM, 即将 #content_left 下的子元素移动到 lists
             * 注意:需要提前将 DOM片段 添加到 #content_left下
             */
            addWebUseDomToDom() {
                let container = this.getDomForContainer();
                let lists = this.getDomForLists();
                let items = container.querySelectorAll("#content_left>.c-container");
                let heights = this.getListsHeight();
                let frames = [];
                //初始化
                for (let i = 0, length = lists.length; i < length; i++) {
                    //缓存
                    frames.push(document.createDocumentFragment());
                }
                //将 item 添加到虚拟DOM中
                for (let i = 0, item; (item = items[i++]);) {
                    //获取最小的高度值
                    let minHeight = Reflect.apply(Math.min, null, heights);
                    //获取最小的高度的索引值
                    let index = heights.indexOf(minHeight);
                    //添加到高度
                    heights[index] += item.clientHeight;
                    //缓存
                    frames[index].appendChild(item);
                }
                //添加到真实DOM
                for (let i = 0, length = lists.length; i < length; i++) {
                    Baidu.delayRun(() => {
                        lists[i].appendChild(frames[i]);
                    }, i);
                }
            }
            /**
             * 02 - 添加内容到lists
             *
             *
             * @param frame DOM片段
             */
            addWebUseFrameToDom(frame) {
                //获取lists
                let lists = this.getDomForLists();
                //获取列表合集
                let items = frame.getElementsByClassName("c-container");
                //获取初始化高度集合
                let heights = this.getListsHeight();
                //将 item 添加到list中
                for (let i = 0, item; (item = items[i]);) {
                    //获取高度合集
                    //获取最小的高度值
                    let minHeight = Reflect.apply(Math.min, null, heights);
                    //获取最小的高度的索引值
                    let index = heights.indexOf(minHeight);
                    //添加到list中
                    lists[index].appendChild(item);
                    //更新高度
                    heights = this.getListsHeight();
                }
            }
            /**
             * 03 - 添加内容到 lists
             * 使用"模拟高度"进行添加
             *
             * @param frame DOM片段
             */
            addWebUseVirtualToDom(frame) {
                let lists = this.getDomForLists();
                let frames = [];
                //获取列表合集
                let items = frame.getElementsByClassName("c-container");
                if (items.length <= 0) {
                    return;
                }
                //获取初始化高度集合
                let heights = this.getListsHeight();
                //初始化
                for (let i = 0, length = lists.length; i < length; i++) {
                    frames[i] = document.createDocumentFragment();
                }
                //将 item 添加到list中
                for (let i = 0, item; (item = items[i]);) {
                    //获取最小的高度值
                    let minHeight = Reflect.apply(Math.min, null, heights);
                    //获取最小的高度的索引值
                    let index = heights.indexOf(minHeight);
                    //获取模拟高度
                    heights[index] += this.getItemVirtualHeight(item);
                    //添加到list中
                    frames[index].appendChild(item);
                }
                Baidu.delayRun(() => {
                    //插入内容到list
                    for (let i = 0, length = lists.length; i < length; i++) {
                        lists[i].appendChild(frames[i]);
                    }
                }, 1);
            }
            /**
             * 是否存在list节点
             */
            hasListNode() {
                let lists = this.getDomForLists();
                return lists.length > 0;
            }
            /**
             * 向网页添加列表
             */
            insertListNode() {
                let layoutType = this.layoutType;
                let container = this.getDomForContainer();
                let frame = document.createDocumentFragment();
                //创建list节点
                for (let i = 1, div, length = layoutType; i < length; i++) {
                    div = document.createElement("div");
                    div.id = "list" + i;
                    div.className = "list";
                    frame.appendChild(div);
                }
                //将节点插入到文档中
                container.insertBefore(frame, container.firstChild);
                return this;
            }
            /**
             * 添加内容到 lists
             */
            addListContent(frame) {
                this.resetDOM();
                Baidu.delayRun(() => {
                    this.addWebUseVirtualToDom(frame);
                }, 0);
            }
            /**
             * 初始化
             */
            init() {
                try {
                    this.resetDOM();
                    if (!this.hasListNode()) {
                        //插入list节点并刷新节点
                        this.insertListNode();
                    }
                    this.addWebUseDomToDom();
                }
                catch (error) {
                    console.error(error);
                }
            }
            /**
             * 执行
             */
            execute() {
                if (this.isMulLayout()) {
                    Baidu.ready = () => {
                        this.init();
                    };
                }
            }
        }
        /**
         * 自动加载下一页
         * @class AutoLoadNextPage
         */
        class AutoLoadNextPage {
            /**
             * 构造函数
             */
            constructor() {
                //赋值
                this.GM = GM;
                //DOM
                this.DOM = Baidu.DOM;
                //实例化 - 多页布局
                this.MulpageLayout = new MulPageLayout();
                //实例化 - 重定向
                this.Redirect = new Redirect();
                //实例化 -
                this.Parser = new DOMParser();
                //减少频率
                this.Reduce = new ReduceExecute();
                this.isExecute = Boolean(this.GM.getValue(Options.SWITCH_IS_LOADPAGE));
            }
            /**
             * 重置
             */
            reset() {
                //是否第一次执行
                this.isFirstRun = true;
                //是否导入过
                (this.isImport = false),
                    //下一页真实地址
                    (this.realNextURL = null);
                //模板地址
                this.templateURL = null;
                //步进值(默认值)
                this.step = 0;
                //每页起始值
                this.count = 0;
                //偏移高度
                this.offsetHight = 1000;
                //缓存
                this.cache = [];
                //缓存量
                this.cacheSize = 1;
                //节点缓存
                this.container = this.DOM.getElementById("content_left");
            }
            /**
             * 获取真实下一个的地址
             * @returns {string} 下一页地址
             */
            getNextPageRealURL() {
                if (!this.realNextURL) {
                    let page = document.getElementById("page");
                    this.realNextURL = page
                        .getElementsByClassName("n")[0]
                        .getAttribute("href");
                }
                return this.realNextURL;
            }
            /**
             * 获取步进值
             * @returns {number} 步进值
             */
            getNextPageStepValue() {
                if (!this.step) {
                    //提取 &pn=20 中的20
                    let regParam = /(&pn=\d+)/;
                    let regValue = /\d+/;
                    let result = regParam.exec(this.getNextPageRealURL());
                    this.step = Number(regValue.exec(result));
                }
                return this.step;
            }
            /**
             * 获取模板地址
             * @returns {string} this.templateURL: 模板地址
             */
            getTempletURL() {
                this.templateURL =
                    this.templateURL ||
                        this.getNextPageRealURL().replace(/&pn=\d+/, "");
                return this.templateURL;
            }
            /**
             * 获取下一页合成地址
             * @returns {sting} 下一页的地址
             */
            getNextPageComposeURL() {
                this.count += this.getNextPageStepValue();
                return this.getTempletURL() + `&pn=${this.count}`;
            }
            /**
             * 判断是否存在缓存
             * @returns {boolean} 存在: true
             * @returns {boolean} 不存在:false
             */
            hasCache() {
                return this.cache.length >= this.cacheSize;
            }
            /**
             * 将响应文本添加到缓存中
             * @param responseText 响应文本
             */
            addCache(responseText) {
                //转化为DOM对象
                let reg = /<body[\s\S.]+<\/body>/;
                let parser = this.Parser;
                let htmlDoc = parser.parseFromString(reg.exec(responseText)[0], "text/html");
                //获取Items
                let items = htmlDoc
                    .getElementById("content_left")
                    .getElementsByClassName("c-container");
                //添加到缓存
                let frame = document.createElement("div");
                //appendchild 自动执行迭代器 导致 i++ (小心);
                for (let i = 0, item; (item = items[i]);) {
                    frame.appendChild(item);
                }
                //加入缓存
                this.cache.push(frame);
            }
            /**
             * 监测滚动位置
             */
            checkScrollPosition() {
                if (this.Reduce.isNormalExecute()) {
                    this.Reduce.stopNormalExecute().regainNormalExecute(5);
                    let element = document.documentElement, clientHeight = element.clientHeight, scrollTop = element.scrollTop ||
                        window.pageYOffset ||
                        document.body.scrollTop ||
                        0, scrollHeight = Number(element.scrollHeight);
                    //判断
                    if (clientHeight + scrollTop + this.offsetHight >
                        scrollHeight) {
                        this.removeScrollEvent();
                        this.task();
                    }
                }
            }
            /**
             * 移除滚动事件
             */
            removeScrollEvent() {
                document.onscroll = event => {
                    let e = event || window.event;
                    e.preventDefault();
                };
                return this;
            }
            /**
             * 绑定滚动触发事件
             */
            bindScrollEvent() {
                document.onscroll = () => {
                    this.checkScrollPosition();
                };
            }
            /**
             * 将 DOM 插入到相应的位置
             */
            addItemsToWeb() {
                //插入内容到DOM节点
                if (this.MulpageLayout.isMulLayout()) {
                    this.MulpageLayout.addListContent(this.cache.shift());
                }
                else {
                    this.container.innerHTML += this.cache.shift().innerHTML;
                }
            }
            /**
             * 发送请求
             */
            requireNextPageContent() {
                this.GM.xmlhttpRequest({
                    method: "GET",
                    url: this.getNextPageComposeURL(),
                    timeout: 3000,
                    responseType: "text",
                    onload: response => {
                        if (response.status === 200 ||
                            response.status === 304) {
                            //如果不存在缓存,再发一次
                            if (!this.hasCache()) {
                                this.requireNextPageContent();
                            }
                            //添加响应文本到缓存
                            this.addCache(response.responseText);
                            //开始导入数据到网页
                            if (!this.isImport) {
                                this.import();
                            }
                        }
                    },
                    onerror: response => {
                        console.error(response);
                    }
                });
            }
            /**
             * 导入数据到网页
             */
            import() {
                this.isImport = true;
                //添加内容到网页
                this.addItemsToWeb();
                //重定向
                this.Redirect.execute();
                //绑定滚动事件
                Baidu.delayRun(() => {
                    this.removeScrollEvent().bindScrollEvent();
                }, 3);
            }
            /**
             * 任务调度
             * @param URL
             */
            task() {
                //设置有导入过
                this.isImport = false;
                //发送请求
                this.requireNextPageContent(); //如果有缓存
                //如果存在缓存
                if (this.hasCache()) {
                    this.import();
                }
            }
            /**
             * 隐藏元素
             */
            hideElement() {
                let page = document.getElementById("page");
                page.style.visibility = "hidden";
            }
            /**
             * 初始化
             */
            init() {
                //重置配置
                this.reset();
                //开始加载
                this.task();
                //隐藏元素
                Baidu.delayRun(() => {
                    this.hideElement();
                }, 3);
            }
            /**
             * 入口
             * @returns {void}
             */
            execute() {
                if (this.isExecute) {
                    Baidu.ready = () => {
                        this.init();
                    };
                }
            }
        }
        /**
         * 重定向
         * @class Redirect
         */
        class Redirect {
            constructor() {
                this.GM = GM;
                this.DOM = Baidu.DOM;
                //重定向后需添加类名(防止重复重定向)
                this.redirectClassName = "isredirect";
                //是否执行
                this.isExecute = Boolean(this.GM.getValue(Options.SWITCH_IS_REDIRECT));
            }
            /**
             * 重定向
             * @param item a节点
             */
            redirect(item) {
                this.GM.xmlhttpRequest({
                    method: "HEAD",
                    url: item.href,
                    onload: response => {
                        let realURL = response.finalUrl;
                        item.href = realURL;
                        //加入重定向标志
                        item.className = this.redirectClassName;
                        //移除不必要的属性
                        item.removeAttribute("data-click");
                    }
                });
            }
            /**
             * 开始
             */
            start() {
                let container = this.DOM.getElementById("content_left");
                let items = container.querySelectorAll("h3>a:not([class])");
                for (let i = 0, item; (item = items[i++]);) {
                    //延时执行
                    Baidu.delayRun(() => {
                        this.redirect(item);
                    }, i);
                }
            }
            /**
             * 初始化
             */
            init() {
                this.start();
            }
            /**
             * 执行
             */
            execute() {
                if (this.isExecute) {
                    Baidu.ready = () => {
                        Baidu.delayRun(() => {
                            this.init();
                        }, 5);
                    };
                }
            }
        }
        /**
         * 回到顶部
         * @class BackToTop
         */
        class BackToTop {
            /**
             * 单击回到顶部
             */
            bindClick() {
                let container = document.getElementsByClassName("s_form")[0];
                container.onclick = event => {
                    let e = event || window.event;
                    let isContainer = e.target
                        ? e.target === container
                        : e.srcElement === container;
                    if (isContainer) {
                        //setInterval方案
                        let element = document.documentElement;
                        let body = document.body;
                        let node = element.scrollTop ? element : body;
                        let top = node.scrollTop;
                        let step = top / 20;
                        let timer = setInterval(() => {
                            if (node.scrollTop <= 0) {
                                node.scrollTop = 0;
                                clearInterval(timer);
                            }
                            node.scrollTop -= step;
                        }, 10);
                        e.stopPropagation();
                    }
                };
            }
            /**
             * 初始化
             */
            init() {
                this.bindClick();
            }
            /**
             * 执行
             */
            execute() {
                Baidu.ready = () => {
                    Promise.resolve().then(() => {
                        Baidu.delayRun(() => {
                            this.init();
                        }, 10);
                    });
                };
            }
        }
        /**
         * 谷歌
         * 双击使用 google 搜索
         * @class Google
         */
        class Google {
            googleSearch() {
                let googlePath = "https://www.google.com/search?q=";
                let searchContent = document.getElementById("kw").value.trim();
                let url = googlePath + encodeURIComponent(searchContent);
                window.open(url);
            }
            /**
             * 绑定双击打开Google搜索
             */
            bindDoubleClick() {
                let button = document.getElementById("su");
                button.ondblclick = () => {
                    this.googleSearch();
                };
            }
            /**
             * 初始化
             */
            init() {
                this.bindDoubleClick();
            }
            /**
             * 执行
             */
            execute() {
                Baidu.ready = () => {
                    Promise.resolve().then(() => {
                        this.init();
                    });
                };
            }
        }
        /**
         * 替换首页搜索栏
         * @class ReplaceSearch
         */
        class ReplaceSearch {
            constructor() {
                this.inputId = "baiduinput";
                this.searchPath = "https://www.baidu.com/s?ie=UTF-8&wd=";
            }
            /**
             * 搜索
             */
            search() {
                let value = document.getElementById(this.inputId).value.trim();
                if (value !== "") {
                    location.href = this.searchPath + encodeURIComponent(value);
                }
            }
            /**
             * 绑定提交事件
             */
            bindSubmit() {
                let button = document.getElementById("su");
                button.setAttribute("type", "button");
                button.onclick = event => {
                    let e = event || window.event;
                    this.search();
                    e.stopPropagation();
                };
            }
            /**
             * 检测输入
             */
            bindKeydown() {
                let input = document.getElementById(this.inputId);
                input = document.getElementById("form");
                input.onkeydown = event => {
                    let e = event || window.event;
                    let keyCode = e.keyCode || e.which || e.charCode;
                    if (keyCode === 13) {
                        this.search();
                    }
                    e.stopPropagation();
                };
            }
            /**
             * 插入节点
             * 覆盖原来的搜索框
             */
            insertNode() {
                //屏蔽原来文本输入
                document
                    .getElementById("kw")
                    .setAttribute("disabled", "disabled");
                let container = document.getElementById("s_kw_wrap") ||
                    document.getElementsByClassName("s_ipt_wr")[0];
                let div = document.createElement("input");
                div.id = this.inputId;
                div.type = "text";
                div.autofocus = true;
                div.autocomplete = "off";
                container.appendChild(div);
                //延时聚焦
                Promise.resolve().then(() => {
                    document.getElementById(this.inputId).focus();
                });
            }
            /**
             * 初始化
             */
            init() {
                try {
                    this.insertNode();
                    Promise.resolve().then(() => {
                        this.bindSubmit();
                        this.bindKeydown();
                    });
                }
                catch (e) {
                    throw new Error(e);
                }
            }
            /**
             * 执行
             */
            execute() {
                Baidu.ready = () => {
                    this.init();
                };
            }
        }
        /**
         * 执行广告和无用的节点
         * @class RemoveNode
         */
        class RemoveNode {
            constructor() {
                this.nodes = ["content_right", "content_bottom", "foot"];
                this.style = "display:block !important";
            }
            /**
             * 根据 ID 移除
             */
            removeNodeForID() {
                let items = this.nodes;
                for (let i = 0, item; (item = items[i++]);) {
                    let node = document.getElementById(item);
                    node.parentNode.removeChild(node);
                }
            }
            removeNodeForStyle() {
                let container = document.getElementById("content_left");
                let items = container.querySelectorAll(`#content_left>div[style*="${this.style}"]`);
                for (let i = 0, item; (item = items[i++]);) {
                    item.parentNode.removeChild(item);
                }
            }
            /**
             */
            init() {
                try {
                    this.removeNodeForID();
                }
                catch (error) { }
            }
            /**
             * 执行
             */
            execute() {
                Baidu.ready = () => {
                    this.init();
                };
            }
        }
        /**
         * 快捷键
         * @class ShortcutKeys
         */
        class ShortcutKeys {
            constructor() {
                this.Google = new Google();
                this.filters = Config.FILTERS;
                this.target = null;
                this.KEY_ENTER = 13;
                this.KEY_ALT = 18;
                this.KEY_SHIFT = 16;
                this.KEY_CTRL = 17;
                this.KEY_GOOGLE = "G";
            }
            /**
             * 过滤搜索
             */
            filterSearch(filterName) {
                //移除如 "-baijiahao" 正则
                let reg1 = /\s\-\S+/;
                //移除如 "site:baidu" 正则
                let reg2 = /\ssite\:\S+/;
                let URL = "https://www.baidu.com/s?ie=utf-8&wd=";
                let content = document.getElementById("kw").value.trim();
                content = content.replace(reg1, "").trim();
                content = content.replace(reg2, "").trim();
                location.href =
                    URL + encodeURIComponent(content) + " " + filterName;
            }
            /**
             * 选择全部
             */
            selectAllContent() {
                let input = document.getElementById("kw");
                input.focus();
                input.selectionStart = 0;
                input.selectionEnd = input.value.length;
            }
            /**
             * 绑定快捷键
             */
            bindKeys() {
                let defaultTarget = this.target;
                document.onkeyup = event => {
                    let e = event || window.event;
                    if (e.target === defaultTarget || e.target === document) {
                        let keyCode = e.keyCode || e.which || e.charCode;
                        //Ctrl + Enter 全选中
                        if (keyCode == this.KEY_ENTER && e.ctrlKey) {
                            this.selectAllContent();
                            return;
                        }
                        //谷歌搜索
                        if (keyCode ===
                            this.KEY_GOOGLE.toUpperCase().charCodeAt() && !e.altKey && !e.shiftKey && !e.ctrlKey && !e.metaKey) {
                            this.Google.googleSearch();
                            return;
                        }
                        //过滤搜索
                        for (let { name, value } of this.filters) {
                            if (keyCode === name.toUpperCase().charCodeAt() && !e.altKey && !e.shiftKey && !e.ctrlKey && !e.metaKey) {
                                this.filterSearch(value);
                                return;
                            }
                        }
                    }
                    e.stopPropagation();
                };
            }
            /**
             * 重置
             */
            reset() {
                this.target = document.getElementsByTagName("body")[0] || null;
            }
            /**
             * 初始化
             */
            init() {
                try {
                    this.reset();
                    this.bindKeys();
                }
                catch (error) { }
            }
            /**
             * 执行
             */
            execute() {
                Baidu.ready = () => {
                    this.init();
                };
            }
        }
        /**
         * Base地址重置
         */
        class BaseURL {
            run() {
                location.href = location.href.replace("https://www.baidu.com/#", "https://www.baidu.com/s?");
            }
        }
        /**
         *  首页
         */
        class PageIndex {
            run() {
                //组合模式
                let command = new Commond();
                command.add(new ImportIndexStyle());
                command.add(new ReplaceSearch());
                command.execute();
            }
        }
        /**
         *  搜索结果页
         */
        class PageCommon {
            run() {
                /**
                 * 01 - 初始化执行
                 */
                let command = new Commond();
                command.add(new ImportCommonStyle());
                command.add(new MenuButton());
                command.add(new MulPageLayout());
                command.add(new AutoLoadNextPage());
                command.add(new Redirect());
                command.add(new BackToTop());
                command.add(new Google());
                command.add(new ShortcutKeys());
                command.execute();
                /**
                 * 02 - 设置标志位
                 * 防止后期多次无用执行
                 */
                let avoidMulExecute = new AvoidMulExecute();
                //设置标志位
                Baidu.ready = () => {
                    avoidMulExecute.setSign();
                };
                /**
                 * 03 - 监测 DOM
                 */
                //调用函数
                let mutationfunc = () => {
                    //只执行一次
                    if (!avoidMulExecute.hasSign()) {
                        //设置标志位
                        avoidMulExecute.setSign();
                        //清除缓存
                        Baidu.DOM.deleteCache();
                        //执行
                        command.execute();
                    }
                };
                //加载完成后 - 根据 DOM 变化重新执行函数( 防止Bash值改变时不触发脚本)
                window.onload = () => {
                    let MutationObserver = window.MutationObserver ||
                        window.WebKitMutationObserver ||
                        window.MozMutationObserver;
                    if (!!MutationObserver) {
                        let observer = new MutationObserver(mutationfunc);
                        let wrapper = document.querySelector("#wrapper");
                        let observerConfig = {
                            childList: true,
                            subtree: true
                            //"attributes": true,
                            //"characterData":true,
                            //"attributesFilter": ["class"],
                        };
                        //开始观察
                        observer.observe(wrapper, observerConfig);
                    }
                    else {
                        console.error("百度搜索-优化: 浏览器不兼容 MutationObserver 接口, 请升级浏览器版本");
                    }
                };
            }
        }
        /**
         * 简单工厂
         */
        class Factory {
            /**
             *
             * @param url
             */
            static create(url) {
                //BASE地址(BASE地址会导致样式跳转,需要重定向)
                const URL_BASE = "https://www.baidu.com/#";
                //普通页 01
                const URL_COMMON_01 = "https://www.baidu.com/s";
                //普通页 02
                const URL_COMMON_02 = "https://www.baidu.com/baidu";
                //首页
                const URL_INDEX = "https://www.baidu.com";
                //返回BASE
                if (url.startsWith(URL_BASE)) {
                    return new BaseURL();
                }
                //返回结果页
                if (url.startsWith(URL_COMMON_01)) {
                    return new PageCommon();
                }
                //返回结果页
                if (url.startsWith(URL_COMMON_02)) {
                    return new PageCommon();
                }
                //返回首页
                if (url.startsWith(URL_INDEX)) {
                    return new PageIndex();
                }
            }
        }
        /**
         * 启动函数
         */
        Baidu.start = () => {
            Factory.create(location.href).run();
        };
        //返回对象
        return Baidu;
    })(BaiduConfig);
    //启动
    try {
        Baidu.start();
    }
    catch (msg) {
        if (Config.IS_DEBUG) {
            console.error(msg);
        }
    }
})();