// ==UserScript==
// @name 百度搜索 - 优化
// @namespace http://tampermonkey.net/
// @home-url https://gf.qytechs.cn/zh-CN/scripts/31642
// @description 1、屏蔽百度推广 2、关闭百度广告联盟信息收集 3、绑定快捷键 4、布局调整 5、居中单列(可选) 6、居中双列(可选)
// @version 4.0.5
// @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://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
// ==/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 `<li><input type='radio' name='page' value='${layoutType}' ${checked}>${content}</li>`;
}
/**
* 获得 HTML - 功能选项选项
* @param content 显示的内容
* @param selection 功能配置
*/
getContentFunSelect(content, selection) {
let key = selection.name;
let checked = this.GM.getValue(selection) ? "checked" : "";
return `<li><input type='checkbox' name='use' value='${key}' ${checked}>${content}</li>`;
}
/**
* 获得 HTML - 保存
* @param content 显示的内容
*/
getContentSava(content) {
let id = Config.MENU_SAVA_ID;
return `<input id='${id}' 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("使用重定向", 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 += "</ol>";
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 = `<div>${content}</div>`;
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");
}
//获取list高度合集
getListHeight() {
let heights = [];
let lists = this.container.getElementsByClassName("list");
for (let i = 0, list; (list = lists[i++]);) {
heights.push(list.clientHeight);
}
return heights;
}
//添加内容到list
addListContent(frame) {
this.refresh();
//退出
if (this.lists.length <= 0) {
return;
}
//获取合集
let items = frame.getElementsByClassName("c-container");
//将 item 添加到list中
for (let i = 0, item; item = items[i];) {
//获取高度合集
let heights = this.getListHeight();
//获取最小的高度值
let minHeight = Reflect.apply(Math.min, null, heights);
//获取最小的高度的索引值
let index = heights.indexOf(minHeight);
//添加到list中
this.lists[index].appendChild(item);
}
}
/**
* 移动节点
*/
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 = 600;
//缓存
this.cache = [];
//缓存量
this.cacheSize = 1;
this.layoutType = this.GM.getValue(Options.SELECT_PAGE);
//节点缓存
this.container = document.getElementById("content_left");
}
/**
* 判断是否存在缓存
* @returns {boolean} 存在: true
* @returns {boolean} 不存在:false
*/
hasCache() {
return this.cache.length >= this.cacheSize;
}
/**
* 获取真实下一个的地址
* @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 = /<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);
}
/**
* 将缓存的 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() {
//插入内容到DOM节点
let layoutType = this.layoutType;
if (layoutType === "3" || layoutType === "4") {
this.MulpageLayout.addListContent(this.cache.shift());
}
else {
this.container.innerHTML += this.cache.shift().innerHTML;
}
//this.importDomToWeb();
//this.MulpageLayout.execute();
this.Redirect.execute();
this.isScrollCall = false;
}
/**
* 导入数据到网页
*/
startImport() {
//如果是第一次执行
if (this.isFirstRun) {
this.isFirstRun = false;
//添加内容到网页中
this.importWeb();
//绑定事件
setTimeout(() => {
this.bindEvent();
}, 200);
//如果不是第一次运行并且没有导入过
}
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(); //如果有缓存
//如果存在缓存
if (this.hasCache()) {
this.isImport = true;
this.importWeb();
}
}
/**
* 隐藏元素
*/
hideElement() {
let page = document.getElementById("page");
page.style.visibility = "hidden";
}
/**
* 初始化
*/
init() {
this.reset();
//开始加载
this.loadNextPage();
//隐藏元素
this.hideElement();
}
/**
* 入口
* @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() {
//屏蔽原来文本输入
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);
//延时聚焦
setTimeout(() => {
document.getElementById(this.inputId).focus();
}, 1);
}
/**
* 初始化
*/
init() {
try {
this.insertNode();
setTimeout(() => {
this.bindSubmit();
this.bindKeydown();
}, 20);
}
catch (e) {
throw new Error(e);
}
}
/**
* 执行
*/
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();
};
}
}
/**
* 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() {
//网址重定向 - 防止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) {
//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);
}
}
})();