// ==UserScript== // @name 百度搜索 - 优化 // @namespace http://tampermonkey.net/ // @home-url https://greasyfork.org/zh-CN/scripts/31642 // @description 1、屏蔽百度推广 2、关闭百度广告联盟信息收集 3、绑定快捷键 4、布局调整 5、居中单列(可选) 6、居中双列(可选) // @version 4.0.2 // @author 浮生未歇 // @run-at document-start // @include https://www.baidu.com/ // @include https://www.baidu.com/s?* // @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://SSHIN.coding.me/Baidu/2018-10-30/indexStyle.css // @resource baiduCommonStyle https://SSHIN.coding.me/Baidu/2018-10-30/commonStyle.css // @resource baiduMenu https://SSHIN.coding.me/Baidu/2018-10-30/menu.css // @resource baiduOne https://SSHIN.coding.me/Baidu/2018-10-30/one.css // @resource baiduTwo https://SSHIN.coding.me/Baidu/2018-10-30/two.css // @resource baiduThree https://SSHIN.coding.me/Baidu/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 // @downloadURL none // ==/UserScript== (() => { //初始化配置 const Config = { //是否调试 IS_DEBUG: true, //壁纸地址 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") } ], //跳转搜索关键字 JUMP_KEY: "@", //跳转搜索 数据 JUMP_DATA: [ { name: "贴吧", value: "http://tieba.baidu.com/f?fr=wwwt&kw=%s" }, { name: "知道", value: "https://zhidao.baidu.com/search?word=%s" }, { name: "图片", value: "http://image.baidu.com/search/index?tn=baiduimage&word=京东" }, { name: "软件", value: "https://pc.qq.com/search.html#!keyword=%s" }, { name: "淘宝", value: "https://s.taobao.com/search?q=%s" } ], //过滤搜索 关键字 SEARCH_KYE: "#", //过滤搜索 数据 SEARCH_DATA: [ { name: "知道", value: "zhidao.baidu.com" }, { name: "破解", value: "52pojie.cn" }, { name: "csdn", value: "blog.csdn.net" } ] }; //打包 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(){} */ Object.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"); } } }); /** * 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 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() { for (let i = 0, command; (command = this.commondList[i++]);) { if (command.execute()) { break; } } } } /** * 检测功能 - 避免代码多次执行 * @class AvoidMulExecute */ class AvoidMulExecute { constructor() { //标志名称 this.signName = "isRun"; } /** * 添加标志 * @method addSign */ addSign() { let signName = this.signName; let container = document.getElementById("content_left"); let isExecute = container.hasAttribute(signName); if (isExecute) { return true; } else { container.setAttribute(signName, "true"); return false; } } /** * 初始化 * @method init */ init() { this.addSign(); } /** * 执行 * @method excute */ execute() { Baidu.ready = () => { this.init(); }; } } /** * 重定向搜索地址 * @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; } /** * 样式 - 背景 * @method styleForBackground * @returns {string} 样式 */ styleForBackground() { let selection = this.Options.SWITCH_IS_BACKGOUND; let isExecute = this.GM.getValue(selection); let defaultURL = this.backgoundURL; if (isExecute) { 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}`; } else { return ""; } } /** * 样式 - 固定侧边栏 * @method styleForFixedSilder * @returns {string} 样式 */ styleForFixedSilder() { let selection = this.Options.SWITCH_IS_FIXEDSILDER; let isExecute = this.GM.getValue(selection); if (isExecute) { return "#s_tab{left:0!important;opacity:1!important;}"; } else { return ""; } } /** * 样式 - 页面布局 * @method styleForPageLayout * @returns {string} 样式 */ styleForPageLayout() { let selection = this.Options.SELECT_PAGE; let layout = this.GM.getValue(selection); switch (layout) { 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; } /** * 获得 HTML - 页面布局选项 * @param content 显示的内容 * @param layoutType 页面布局类型 */ getContentPageSelect(content, layoutType) { let selection = this.Options.SELECT_PAGE; let checked = this.GM.getValue(selection) === layoutType ? "checked" : ""; return `
  • ${content}
  • `; } /** * 获得 HTML - 功能选项选项 * @param content 显示的内容 * @param selection 功能配置 */ getContentFunSelect(content, selection) { let key = selection.name; let checked = this.GM.getValue(selection) ? "checked" : ""; return `
  • ${content}
  • `; } /** * 获得 HTML - 保存 * @param content 显示的内容 */ getContentSava(content) { let id = Config.MENU_SAVA_ID; return ``; } //获取整体 HTML getContent() { let content = ""; content += "
      页面选择"; content += this.getContentPageSelect("普通页面", "1"); content += this.getContentPageSelect("单页居中", "2"); content += this.getContentPageSelect("双页居中", "3"); content += this.getContentPageSelect("三页居中", "4"); content += "
    "; content += "
      功能选择"; content += this.getContentFunSelect("使用重定向", Options.SWITCH_IS_REDIRECT); content += this.getContentFunSelect("自动下一页", Options.SWITCH_IS_LOADPAGE); content += this.getContentFunSelect("固定侧边栏", Options.SWITCH_IS_FIXEDSILDER); content += this.getContentFunSelect("加载背景", Options.SWITCH_IS_BACKGOUND); content += "
    "; content += this.getContentSava("保存"); return content; } /** * 绑定保存事件 */ bindSavaClick() { let sava = document.getElementById(Config.MENU_SAVA_ID); sava.onclick = event => { //页面布局选项 let radios = document.getElementsByName("page"); 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("use"); 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); } } event.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 = `
    ${content}
    `; container.appendChild(div); } /** * 初始化 */ init() { let isExecute = document.getElementById(Config.MENU_PAGE_ID); if (!isExecute) { this.insertNode(); setTimeout(() => { this.bindSavaClick(); }, 600); } } /** * 执行 */ 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 container = document.getElementById("container"); let items = document.getElementById(Config.MENU_PAGE_ID); let isScreenClick = event.target && event.target == container; if (isScreenClick) { items.style.display = "none"; } }; } /** * 单击打开功能选项页 */ bindClick() { let container = document.getElementById(Config.MENU_BUTTON_ID); container.onclick = 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"; } //阻止冒泡 event.stopPropagation(); }; } /** * 插入节点 */ insertNode() { let container = document.getElementById("u"); let div = document.createElement("div"); div.id = Config.MENU_BUTTON_ID; div.innerHTML = "自定义"; container.appendChild(div); } /** * 初始化 */ init() { let isExecute = document.getElementById(Config.MENU_BUTTON_ID); if (!isExecute) { this.insertNode(); //修复未登录错位问题 setTimeout(() => { this.fixedNoLoginButtonPosition(); }, 20); //延时绑定事件 setTimeout(() => { this.bindClick(); this.bindClickHide(); }, 600); } } /** * 执行 */ execute() { Baidu.ready = () => { this.init(); }; //执行菜单功能面板 this.MenuItemsOptions.execute(); } } /** * 多页布局 * @class MUlPageLayout */ class MulPageLayout { constructor() { this.GM = GM; this.container = null; this.lists = null; } /** * 刷新数据 */ refresh() { this.container = document.getElementById("content_left"); this.lists = this.container.getElementsByClassName("list"); } /** * 移动节点 */ moveNode() { let lists = this.lists; let items = this.container.querySelectorAll("#content_left>.c-container"); let heights = []; let frames = []; //退出 if (items.length < 1) { return; } //初始化 for (let i = 0, list; (list = lists[i++]);) { //获取高度合集 heights.push(list.clientHeight); //缓存 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++) { lists[i].appendChild(frames[i]); } } /** * 向网页添加列表 * @param layoutType 页面布局类型 */ insertNode(layoutType) { let isExecute = this.lists.length > 0; if (!isExecute) { let container = this.container; let frame = document.createDocumentFragment(); 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); //隐藏节点 this.hideNode(); } } /** * 隐藏节点 */ hideNode() { let style = new Style(); let content = "#content_left>.c-container{visibility:hidden!important}"; style.add(content).end(); } /** * 初始化 * @param layoutType */ init(layoutType) { try { this.refresh(); this.insertNode(layoutType); this.moveNode(); } catch (error) { console.error(error); } } /** * 执行 */ execute() { let selection = Options.SELECT_PAGE; let layoutType = this.GM.getValue(selection); let isExecute = layoutType === "3" || layoutType === "4"; if (isExecute) { Baidu.ready = () => { this.init(layoutType); }; } } } /** * 自动加载下一页 * @class AutoLoadNextPage */ class AutoLoadNextPage { /** * 构造函数 */ constructor() { //赋值 this.GM = GM; //实例化 - 多页布局 this.MulpageLayout = new MulPageLayout(); //实例化 - 重定向 this.Redirect = new Redirect(); //实例化 - this.Parser = new DOMParser(); } /** * 重置 */ reset() { //是否第一次执行 this.isFirstRun = true; //是否发生滚动调用 this.isScrollCall = false; //是否导入过 (this.isImport = false), //下一页真实地址 (this.realNextURL = null); //模板地址 this.templateURL = null; //步进值(默认值) this.step = null; //每页起始值 this.count = 0; //偏移高度 this.offsetHight = 800; //缓存 this.cache = []; //节点缓存 this.container = document.getElementById("content_left"); } /** * 判断是否存在缓存 * @returns {boolean} 存在: true * @returns {boolean} 不存在:false */ hasCache() { return this.cache.length > 0; } /** * 获取真实下一个的地址 * @returns {string} 下一页地址 */ getNextPageRealURL() { if (!this.realNextURL) { let page = document.getElementById("page"); this.realNextURL = page.getElementsByClassName("n")[0].href; } return this.realNextURL; } /** * 获取真实一页的条目数 * @returns {number} 条目数 */ getStepParamValue() { //提取 &pn=20 中的20 let regParam = /(&pn=\d+)/; let regValue = /\d+/; let result = regParam.exec(this.getNextPageRealURL()); return Number(regValue.exec(result)[0]); } /** * 获取模板地址 * @returns {string} this.templateURL: 模板地址 */ getTempletURL() { this.templateURL = this.templateURL || this.getNextPageRealURL().replace(/&pn=\d+/, ""); return this.templateURL; } /** * 获取步进值 * @returns {number} 步进值 */ getStepValue() { this.step = this.step || this.getStepParamValue(); return this.step; } /** * 获取下一页合成地址 * @returns {sting} 下一页的地址 */ getNextPageComposeURL() { this.count += this.getStepValue(); return this.getTempletURL() + `&pn=${this.count}`; } /** * 将响应文本添加到缓存中 * @param responseText 响应文本 */ addCache(responseText) { //转化为DOM对象 let reg = //; 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.createDocumentFragment(); //appendchild 自动执行迭代器 导致 i++ (小心); for (let i = 0, item; (item = items[i]);) { frame.appendChild(item); } //加入缓存 this.cache.push(frame); } /** * 将缓存的 DOM节点 插入到网页中 */ importDomToWeb() { let container = this.container; let items = this.cache.shift(); container.appendChild(items); } /** * 绑定滚动触发事件 */ bindEvent() { document.onscroll = () => { if (!this.isScrollCall) { //获取值 let element = document.documentElement, clientHeight = element.clientHeight, scrollTop = element.scrollTop || window.pageYOffset || document.body.scrollTop || 0, scrollHeight = element.scrollHeight; //判断 if (clientHeight + scrollTop + this.offsetHight > scrollHeight) { this.loadNextPage(); } } }; } /** * 将 DOM 插入到相应的位置 */ importWeb() { this.importDomToWeb(); this.MulpageLayout.execute(); this.Redirect.execute(); this.isScrollCall = false; } /** * 导入数据到网页 */ startImport() { //如果是第一次执行 if (this.isFirstRun) { this.isFirstRun = false; //添加内容到网页中 this.importWeb(); //绑定事件 setTimeout(() => { this.bindEvent(); }, 600); //如果不是第一次运行并且没有导入过 } else if (!this.isImport) { this.isImport = true; this.importWeb(); } } /** * 发送请求 */ 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); //开始导入数据到网页 this.startImport(); } }, onerror: response => { console.error(response); } }); } /** * 加载下一页 * @param URL */ loadNextPage() { //开启调用 this.isScrollCall = true; //设置有导入过 this.isImport = false; //发送请求 this.requireNextPageContent(); } /** * 初始化 */ init() { this.reset(); //开始加载 this.loadNextPage(); } /** * 入口 * @returns {void} */ execute() { let selection = Options.SWITCH_IS_LOADPAGE; let isExecute = this.GM.getValue(selection); if (isExecute) { Baidu.ready = () => { this.init(); }; } } } /** * 重定向 * @class Redirect */ class Redirect { constructor() { this.GM = GM; //重定向后需添加类名(防止重复重定向) this.redirectClassName = "isredirect"; } /** * 重定向 * @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 = document.getElementById("content_left"); let items = container.querySelectorAll("h3>a:not([class])"); for (let i = 0, item; (item = items[i++]);) { this.redirect(item); } } /** * 初始化 */ init() { this.start(); } /** * 执行 */ execute() { let selection = Options.SWITCH_IS_REDIRECT; let isExecute = this.GM.getValue(selection); if (isExecute) { Baidu.ready = () => { this.init(); }; } } } /** * 回到顶部 * @class BackToTop */ class BackToTop { /** * 单击回到顶部 */ bindClick() { let container = document.getElementsByClassName("s_form")[0]; container.onclick = e => { if (e.target === container) { //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 = () => { this.init(); }; } } /** * 谷歌 * 双击使用 google 搜索 * @class Google */ class Google { /** * 绑定双击打开Google搜索 */ bindDoubleClick() { let googlePath = "https://www.google.com/search?q="; let button = document.getElementById("su"); button.ondblclick = e => { let searchContent = document.getElementById("kw").value; window.open(googlePath + searchContent); e.stopPropagation(); }; } /** * 初始化 */ init() { this.bindDoubleClick(); } /** * 执行 */ execute() { Baidu.ready = () => { 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 + value; } } /** * 绑定提交事件 */ bindSubmit() { let button = document.getElementById("su"); button.type = "button"; button.onclick = e => { e.stopPropagation(); this.search(); }; } /** * 检测输入 */ bindKeydown() { let input = document.getElementById(this.inputId); input = document.getElementById("form"); input.onkeydown = e => { e.stopPropagation(); if (e.keyCode === 13) { this.search(); } }; } /** * 插入节点 * 覆盖原来的搜索框 */ insertNode() { 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); //延时聚焦 setTimeout(() => { document.getElementById(this.inputId).focus(); }, 600); } /** * 初始化 */ init() { this.insertNode(); setTimeout(() => { this.bindSubmit(); this.bindKeydown(); }, 600); } /** * 执行 */ execute() { Baidu.ready = () => { this.init(); }; } } /** * 执行广告和无用的节点 * @class RemoveNode */ class RemoveNode { constructor() { this.nodes = ["content_right", "content_bottom", "foot"]; } /** * 根据 ID 移除 */ removeNodeForID() { let items = this.nodes; for (let i = 0, item; (item = items[i++]);) { let node = document.getElementById(item); node.parentNode.removeChild(node); } } /** * 初始化 */ init() { try { this.removeNodeForID(); } catch (error) { } } /** * 执行 */ execute() { Baidu.ready = () => { this.init(); }; } } /** * 快键搜索 (测试中) * @class KeyValueSearch */ class KeyValueSearch { constructor() { this.jumpKey = " " + Config.JUMP_KEY; this.jumpDatas = Config.JUMP_DATA; this.searchKey = " " + Config.SEARCH_KYE; this.searchDatas = Config.SEARCH_DATA; } /** * 跳转到指定页搜索 */ jump(content) { let datas = this.jumpDatas; let key = this.jumpKey; for (let data of datas) { let keyName = data["name"]; let url = data["value"]; let name = key + keyName; if (content.endsWith(name)) { let reg = new RegExp(`${key}\\S+$`); let searchContent = content.replace(reg, ""); location.href = url.replace(/\%s/, searchContent); } } } /** * 过滤搜索 */ search(content) { let key = this.searchKey; let datas = this.searchDatas; let url = location.href; url = url.replace(/&wd=\S+/, ""); url = url.replace(/&si=\S+/, ""); url = url.replace(/&ct=\S+/, ""); for (let data of datas) { let keyName = data["name"]; let address = data["value"]; let name = key + keyName; if (content.endsWith(name)) { let reg = new RegExp(`${key}\\S+$`); let searchContent = content.replace(reg, ""); location.href = `${url}&ct=2097152&si=${address}&wd=${searchContent}`; } } } /** * 检测 */ check(inputContent) { let jump = this.jumpKey; let search = this.searchKey; let content = inputContent; if (content.includes(jump)) { this.jump(content); } else if (content.includes(search)) { this.search(content); } else { return; } } /** * 绑定事件,监测输入 */ bindInputEvent() { let input = document.getElementById("kw"); input.onkeyup = e => { e.stopPropagation(); if (e.keyCode === 13) { let inputContent = input.value.trim(); let regJump = new RegExp(`${this.jumpKey}\\S+$`); let regSearch = new RegExp(`${this.searchKey}\\S+$`); input.value = input.value.replace(regJump, ""); input.value = input.value.replace(regSearch, ""); this.check(inputContent); } }; } /** * 初始化 */ init() { this.bindInputEvent(); } /** * 执行 */ execute() { Baidu.ready = () => { this.init(); }; } } /** * 首页 */ class PageIndex { run() { //组合模式 let command = new Commond(); command.add(new ImportIndexStyle()); command.add(new ReplaceSearch()); command.execute(); } } /** * 搜索结果页 */ class PageCommon { run() { //网址重定向 - 防止Bash值改变时不触发脚本 // Control.run(new RedirectURL()); //执行功能函数 - 主要功能 let command = new Commond(); command.add(new AvoidMulExecute()); command.add(new ImportCommonStyle()); command.add(new RemoveNode()); command.add(new MenuButton()); command.add(new AutoLoadNextPage()); command.add(new MulPageLayout()); command.add(new Redirect()); command.add(new BackToTop()); command.add(new Google()); command.execute(); //执行一次 let mutationfunc = () => { command.execute(); }; //加载完成后 - 根据 DOM 变化重新执行函数( 防止Bash值改变时不触发脚本) window.onload = () => { let MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver || MutationObserver; 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) { //普通页 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"; //返回结果页 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); } } })();