// ==UserScript==
// @name 百度搜索 - 优化 - 测试
// @namespace http://tampermonkey.net/
// @home-url https://greasyfork.org/zh-CN/scripts/31642
// @description 1、屏蔽百度推广 2、关闭百度广告联盟信息收集 3、绑定快捷键 4、布局调整 5、居中单列(可选) 6、居中双列(可选)
// @version 3.0.0
// @author 浮生未歇
// @include http://www.baidu.com/*
// @include https://www.baidu.com/*
// @require https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js
// @resource baiduIndexStyle https://lche.win/baidu/Baidu-2018-04-27/baiduIndexStyle.css
// @resource baiduIndexStyleNo https://lche.win/baidu/Baidu-2018-04-27/baiduIndexStyleNo.css
// @resource baiduCommonStyle https://lche.win/baidu/Baidu-2018-04-27/commonStyle.css
// @resource baiduMyMenuStyle https://lche.win/baidu/Baidu-2018-04-27/customMenuStyle.css
// @resource baiduOnePageStyle https://lche.win/baidu/Baidu-2018-04-27/onePageCenterStyle.css
// @resource baiduTwoPageStyle https://lche.win/baidu/Baidu-2018-04-27/twoPageCenterStyle.css
// @run-at document-body
// @connect *
// @grant GM_addStyle
// @grant GM_getResourceText
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_xmlhttpRequest
// ==/UserScript==
(function() {
'use strict';
// Your code here...
/*
模块:配置
*/
var Config = {
//是否开启DEBUG。true:表示开启,false:表示关闭
isDebug:false,
//是否开启重定向。true:表示开启,false表示关闭
redirect:GM_getValue("redirect",false),
//是否开启自动加载下一页。true:表示开启,false表示关闭
preLoader:GM_getValue("preLoader",false),
//是否导入首页样式
isImportIndexStyple:false,
//Run刷新名称,
runResetElementName:"#isRunReset",
//Run缓存
runCache:[],
//样式缓存
styleCache:[],
//功能选择页。0:表示普通页,1:表示居中单页,2:表示居中双页
option:GM_getValue("option",0),
//监测点元素默认最大高度。监测到点的高度小于该值时,触发脚本
testDefinedMaxHeight:50,
//监测元素默认最小高度
testDefinedMinHeight:5,
//监测点元素
testElementName:"#form",
//样式集
styles:[{
//百度首页
indexStyle : "baiduIndexStyle",
//未登录
indexStyleNo : "baiduIndexStyleNo",
//普通样式
commonStyle : "baiduCommonStyle",
//自定义菜单样式
menuStyle : "baiduMyMenuStyle",
//单页样式
onePageStyle : "baiduOnePageStyle",
//双页样式
towPageStyle : "baiduTwoPageStyle",
}],
//需要安装重置Run的选择器(让函数可以再次运行)
resetSelectors:[
"#page a",
"#su",
"#result_logo",
"#s_kw_wrap",
],
//需要屏蔽的广告
ads:[
"#content_left>div[style*='display:block !important;']",
"#content_left>div[id^='30']",
"#content_left>div:not([id])",
"#content_left>#clone",
],
//需要重定向的元素(重定向过的元素会添加 "redirect"类)
redirectElements:[
"#content_left .c-container h3 > a:not([class*='redirect'])",
],
//重定向地址
redirectURL:"www.baidu.com/link",
//自动加载下一页
preLoaderConfig:[{
//当前域名
hostName : "https://www.baidu.com" ,
//下一页按钮
nextPageButton : "#page a[href*='rsv_page=1']" ,
//页码按钮
pageButton : "#page > a:first",
//条目块
itemSelector : ".c-container" ,
//条目总数可能值(即一页加载多少结果)
itemNums:[10,20,50],
}],
};
/*
模块:Debug
*/
var Debug = {
printDebugInfo:function(name,message){
if(Config.isDebug){
console[name](message);
}
},
group:function(message){
this.printDebugInfo("group",message);
},
groupEnd:function(message){
this.printDebugInfo("groupEnd",message);
},
log:function(message){
this.printDebugInfo("log",message);
},
info:function(message){
this.printDebugInfo("info",message);
},
error:function(message){
this.printDebugInfo("error",message);
},
count:function(message){
this.printDebugInfo("count",message);
}
};
/*
模块:Run运行
*/
var Run = {
_isCache:function(value){
return Config.runCache.indexOf(value) < 0 ? true : false;
},
_addCache:function(value){
Config.runCache.push(value);
},
_removeCache:function(value){
if(Run._isCache()){
var index = Config.runCache.indexOf(value);
Config.runCache.splice(index,1);
}
},
_one:function(name,callback){
return function(){
var value = name + callback;
if(Run._isCache(value)){
try{
Run._addCache(value);
callback();
}catch(e){
Run._removeCache(value);
Debug.error("Run.one() haver error:" + callback);
Debug.error( e );
}
}
};
},
_ready:function(callback){
return function(){
$(document).ready(callback);
};
},
one:function(callback){
this._one("one",callback)();
},
ready:function(callback){
this._ready(callback)();
},
readyOne:function(callback){
this._ready(this._one("readyOne",callback))();
}
};
/*
模块:样式
*/
var Style ={
//加入样式队列
addQueue:function(style){
Config.styleCache.push(style);
},
//开始导入样式(必须先将样式加入队列)
import:function(){
Debug.log("start import style ……");
var styles = Config.styleCache;
var style = null;
for(var i in styles){
style += GM_getResourceText (styles[i]);
Debug.log("import(" + styles[i] + ")style……" );
}
GM_addStyle(style);
Config.styleCache = [];
Debug.log("import success");
},
};
/*
模块:数据
*/
var Data={
getGmValue(name){
return GM_getValue(name,Config[name]);
},
setGmValue(name,value){
GM_setValue(name,value);
},
resetCount(){
Config.count = 0;
},
resetRun(){
Config.runCache = [];
},
resetAll(){
Data.resetCount();
Data.resetRun();
}
};
/*
模块:检查
*/
var Check = {
//获取到顶部的距离
isOffsetHight:function(){
var offsetTopHight = $(Config.testElementName).offset().top;
Debug.log("offsetTopHight : " + offsetTopHight);
// 0 < top < 50
if(Config.testDefinedMinHeight < offsetTopHight && offsetTopHight < Config.testDefinedMaxHeight){
return true;
}else{
return false;
}
},
//页布局 0: 普通页,1:单页居中,2:双页居中
isLayout:function(num){
return Data.getGmValue("option") == num;
},
//存在元素
isExist:function(elementName){
return $(elementName).length > 0;
},
//是否重定向
isRedirect:function(){
return Data.getGmValue("redirect");
},
//是否加载下一页
isPreLoader:function(){
return Data.getGmValue('preLoader');
}
};
//多页布局
var MultiColumnLayout = {
//添加LIST类,用于存放ITEM
addList:function($parent,list,colsum){
var div = null;
if( $parent.children(list).length == 0){
for(var index = colsum ; index > 0 ; index--){
(function(){
div = "<div id='list" + index + " ' class='list'></div>";
$parent.prepend(div);
})();
}
}
},
//将结果移动到list
addItem:function($item){
var $list = $("#content_left > .list");
if($item.length == 0 | $list.length == 0){
return;
}
$item.each(function(){
var heightArray = [] ; //高度集合
var minHightIndex = 0; //最小高度 INDEX
$list.each(function(){
heightArray.push($(this).height());
});
minHightIndex = heightArray.indexOf(Math.min.apply(window,heightArray));
$(this).appendTo($list.eq(minHightIndex));
});
}
};
/*
自动加载下一页
*/
function PreLoader(config){
//当前配置
this.config = config;
//页数计数器 (需要初始化)
this.item_sum = 0;
//页地址 (需要初始化)
this.page_url = null;
//条目集,用于存在请求到结果(需要初始化)
this.items = [];
//第几页(0表示本页)
this.next_page_count = 1;
//请求的网页数据
this.web_page_data = null;
}
PreLoader.prototype={
redirect:function(){
if(Check.isRedirect()){
$(Config.redirectElements.join()).each(function(){
var that = this;
var URL = $(that).attr("href");
if(URL.indexOf(Config.redirectURL) > 0){
$(that).removeAttr("data-click");
GM_xmlhttpRequest({
url:URL,
method:"HEAD",
onload:function(xhr){
//Debug.log("finalUrl:" + xhr.finalUrl);
try{
//将真实地址替换原来地址,并添加标志类(防止再次重定向)
$(that).attr("href",xhr.finalUrl).addClass("redirect");
}catch(e){
Debug.log("重定向发生错误:" + e);
}
},
});
}
});
}
},
getPageURL:function(){
if(this.page_url == null ){
this.page_url = this.config.hostName + $(this.config.pageButton).attr("href");
}
return this.page_url;
},
getItemSum:function(obj){
if(obj.item_sum == 0){
var URL = obj.getPageURL();
obj.config.itemNums.forEach(function(num){
if(URL.indexOf("pn=" + num) > 0){
obj.item_sum = num;
}
});
}
return obj.item_sum;
},
getNextPageURL:function(pageNumber){
var URL = this.getPageURL();
var itemSum = this.getItemSum(this);
return URL.replace(/pn=\d+/g, "pn="+ pageNumber * itemSum);
},
sendRequest:function(that,url){
Debug.log("sendRequest");
$.ajax({
url : url,
async : true,
timeOut : 5000 ,
type : "GET",
dataType : "HTML",
cache : false,
success : function(data,status){
var reg = /<body[\s\S]*<\/body>/g;
var body = reg.exec(data)[0];
var item = $(body).find(that.config.itemSelector);
that.items.push(item);
//console.log(item);
//MultiColumnLayout.addItem($(item));
//that.rediect();
},
error:function(e){
Debug.log("请求失败:" + e);
}
});
},
addDataToWeb:function(obj){
Debug.log("addDataToWeb");
MultiColumnLayout.addItem(obj.items.shift());
obj.redirect();
},
//重置
reset:function(){
this.items = [];
this.next_page_count = 1;
this.page_url = null;
},
//预加载
start:function(callback){
var that = this;
var $element = $("#content_left");
var elementClass = "PreLoaderInit";
var hideElement = ["#rs","#page"];
//如果还没有初始化
if( $element.length > 0 && !$element.hasClass(elementClass)){
console.log("start");
$(hideElement.join()).hide();
$element.addClass(elementClass);
that.reset.call(that);
//第一次预加载
that.load();
//第二次预加载
var timer = setInterval(function(){
if(that.items.length > 0){
clearInterval(timer);
that.load();
callback();
}
},50);
}
},
//正常加载
load:function(){
var that = this;
if(that.items.length > 0){
that.addDataToWeb(that);
}
var url = that.getNextPageURL.call(that,that.next_page_count++);
that.sendRequest(that,url);
}
};
/********************************************************/
/********************** 执行代码 ************************/
/********************************************************/
/*
启动
*/
var Launch = {
//导入首页样式(已登录版)
importIndexStyles:function(){
Style.addQueue(Config.styles[0].indexStyle);
Style.import();
},
//导入首页样式(未登录版)
importIndexStylesNo:function(){
Style.addQueue(Config.styles[0].indexStyleNo);
Style.import();
},
//导入搜索页样式
importStyles:function(itemOption){
var styles = Config.styles[0];
var option = itemOption || Data.getGmValue("option");
Debug.log("option:"+option);
Style.addQueue(styles.commonStyle);
Style.addQueue(styles.menuStyle);
switch(option){
case 1:Style.addQueue(styles.onePageStyle);break;
case 2:Style.addQueue(styles.towPageStyle);break;
}
Style.import();
},
//安装重置配置功能
setClickResetRun:function(){
Debug.log("Run reset ……");
$(Config.resetSelectors.join()).each(function(){
$(this).one('click',function(){
Data.resetAll();
});
});
},
//屏蔽广告
removeAds:function(){
$( Config.ads.join()).remove();
},
//屏蔽再次出现的广告
hideLaterAds:function(){
var $selector = $("#content_left > div[id='1']");
var $result1 = $selector.next().attr('id') == 2;
var $result2 = $("#content_left > div[id]").length != 1;
if($result1){
$selector.attr("id","a1");
}
if($result2){
GM_addStyle("#content_left > div[id='1'],#content_left .result~div[id='1'] {display: none!important;}");
}
},
//屏蔽广告联盟
closeAdsCookie:function(){
var cpro_url = "http://help.wangmeng.baidu.com/cpro.php";
var img = document.createElement("img");
img.src = cpro_url + "?pry=" + 1 + "&_t=" + (new Date()).getTime();
},
//重定向地址
rediect:function(){
if(Check.isRedirect()){
$(Config.redirectElements.join()).each(function(){
var that = this;
var URL = $(that).attr("href");
if(URL.indexOf(Config.redirectURL) > 0){
$(that).removeAttr("data-click");
GM_xmlhttpRequest({
url:URL,
method:"HEAD",
onload:function(xhr){
//Debug.log("finalUrl:" + xhr.finalUrl);
try{
//将真实地址替换原来地址,并添加标志类(防止再次重定向)
$(that).attr("href",xhr.finalUrl).addClass("redirect");
}catch(e){
Debug.log("重定向发生错误:" + e);
}
},
});
}
});
}
},
//插入自定义菜单
inserCustomMenu:function(){
if(Check.isExist("#CustomMenu") ){
return;
}
var parent = "#u";
var content = "";
var div = "";
//1.添加三种排版
content += "<li>普通样式</li> <li>居中单列</li> <li>居中双列</li>";
//2.添加重定向
if(Check.isRedirect()){
content += "<li class='error'>关闭重定向</li>";
}else{
content += "<li class='success'>开启重定向</li>";
}
//3.添加自动加载
if(Check.isPreLoader() ){
content += "<li class='error' title='只对居中双列有效'>关闭自动加载页</li>";
}else{
content += "<li class='success'title='只对居中双列有效'>开启自动加载页</li>";
}
//拼接完整div
div = "<a id='CustomMenu'><ol class='button'><li>自定义</li> </ol> <ol class='menu'>"+ content +"</ol></a>";
$(parent).prepend($(div));
},
//绑定自定义菜单事件
bindCustomMenuEvent:function(){
var $menu = $("#CustomMenu .menu");
var $lis = $("#CustomMenu .menu li");
//自定义菜单点击
$("#CustomMenu").unbind('click').click(function() {
$menu.css("display", "block");
});
//关闭自定义菜单
$(document).unbind('mouseup').mouseup(function(e) {
var _con = $menu;
if(!_con.is(e.target) && _con.has(e.target).length === 0) { // Mark 1
$menu.css("display", "none");
}
});
//自定义菜单选择
$lis .each(function(index){
$(this).unbind('click').click(function(){
//页面布局(0,1,2)
if(0 <= index && index <= 2){
Data.setGmValue("option",index);
}
//重定向(3)
if(index == 3){
if(Check.isRedirect()){
Data.setGmValue("redirect",false); //关闭重定向
}else{
Data.setGmValue("redirect",true); //开启重定向
}
}
//自动加载页(4)
if(index == 4){
if(Check.isPreLoader()){
Data.setGmValue("preLoader",false); //关闭自动加载
}else{
Data.setGmValue("preLoader",true); //开启自动加载
}
}
location.href = location.href;
});
});
},
//双页布局
addTwoList:function(){
var $parent = $("#content_left");
var $item = $("#content_left > .c-container");
var list = "#content_left > .list";
if( $(list).length == 0){
//添加节点(在 content_left 插入 2 个 list )
MultiColumnLayout.addList($parent,list,2);
//添加结果列表(将 item 结果添加到 list 中)
MultiColumnLayout.addItem($item);
}else{
return ;
}
},
//绑定快捷键
bindQuickHotkey:function(){
$(document).keydown(function(event) {
//上一页 Ctrl + <-
if(event.keyCode == 37 && event.ctrlKey) {
$(".n:first").click();
}
//下一页 Ctrl + ->
if(event.keyCode == 39 && event.ctrlKey) {
$(".n:last").click();
}
//搜索框 Ctrl + Enter
if(event.keyCode == 13 && event.ctrlKey ) {
$("#kw").select();
}
});
},
//改变百度首页logo图片
changeBaiduIndexLogo:function(){
var URL = "https://s1.ax1x.com/2018/04/15/CZXxG4.gif";
$("#head #lg>img").attr("src",URL);
},
//初始化加载
init:function(num){
Launch.importStyles(num);
Run.readyOne(Launch.inserCustomMenu); //插入菜单样式
Run.readyOne(Launch.bindCustomMenuEvent); //绑定菜单事件
Run.readyOne(Launch.setClickResetRun); //设置重置器
Run.readyOne(Launch.closeAdsCookie); //关闭百度Cookie收集
Run.readyOne(Launch.bindQuickHotkey); //绑定快捷键
Run.ready(Launch.removeAds); //移除广告
Run.ready(Launch.hideLaterAds); //移除后面再次出现的广告
Run.ready(Launch.rediect); //重定向
}
};
/*****************************************************************************************/
/* 自动加载下一页(只对双页居中有效) - 初始化 */
/*****************************************************************************************/
var preLoader = new PreLoader(Config.preLoaderConfig[0]);
var scrollTop = 0; //获取滚动条到顶部的距离
var scrollHeight = 0; //获取滚动条的高度
var windowHeight = 0; //获取文档区域高度
function scrollLoadPage(){
$(window).unbind("scroll").scroll(function(){
scrollTop = $(this).scrollTop(); //获取滚动条到顶部的距离
scrollHeight = $(this).height(); //获取滚动条的高度
windowHeight = $(document).height(); //获取文档区域高度
if( scrollTop + scrollHeight + 500 >= windowHeight){
$(this).unbind("scroll");
preLoader.load.call(preLoader);
setTimeout(function(){
scrollLoadPage();
},300);
}
});
}
function insertBanner(){
var selector = $("#content_left>#banner");
if(selector.length == 0){
$("#content_left").append("<div title='双击返回顶部' id='banner'></div>");
$("#banner").unbind("dblclick").dblclick(function () {
var speed= "slow";//滑动的速度
$('body,html').animate({ scrollTop: 0 }, speed);
return false;
});
}
}
/*****************************************************************************************/
/* 动态函数 */
/*****************************************************************************************/
function mutationfunc(){
if(Check.isOffsetHight()){
//设置
Config.isImportIndexStyple = true;
try{
Debug.count("multationfunc()执行的次数");
//单页普通布局
if(Check.isLayout(0)){
Launch.init(0);
}
//单页居中布局
if(Check.isLayout(1)){
Launch.init(1);
}
//双页居中布局
if(Check.isLayout(2)){
Launch.init(2);
//添加双列表
Run.ready(Launch.addTwoList);
//自动加载下一页
if(Check.isPreLoader()){
Run.ready(insertBanner);
Run.ready(preLoader.start(scrollLoadPage));
}
}
}catch(e){
Debug.error("mutationfunc()函数出现问题:" + e);
}
}else{
if(!Config.isImportIndexStyple){
Config.isImportIndexStyple = true;
if($("#u1").length > 0){
Launch.changeBaiduIndexLogo();
Launch.importIndexStylesNo();
}else{
Launch.importIndexStyles();
}
}
}
}
try{
//动态监视DOM树的变化
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
if(MutationObserver){
var observer = new MutationObserver(mutationfunc);
var wrapper = document.querySelector("#wrapper");
observer.observe(wrapper, {
'childList': true,
//"attributes": true,
//"subtree":true,
//"characterData":true,
//"attributesFilter": ["class"],
});
// 动态加载函数
mutationfunc();
}else{
//浏览题版本过旧导致不支持MutationObserver
$(document).ready(function(){
// 动态加载函数
console.error("<百度搜索-优化> : 浏览器版本过旧,导致不支持 'MutationObserver' 接口,请升级浏览器");
mutationfunc();
});
}
}catch(e){
Debug.error(e);
}
})();