// ==UserScript== // @name Baidu Search AutoPager // @author Crab // @namespace autopager@baidu.com // @description 百度搜索自动翻页,网站预览图。 // @include /^https?:\/\/www\.baidu\.com\/(?:(?:baidu|s)\?.*|[#?&].*)?$/ // @version 0.7.1 // @grant none // @downloadURL https://update.greasyfork.icu/scripts/12663/Baidu%20Search%20AutoPager.user.js // @updateURL https://update.greasyfork.icu/scripts/12663/Baidu%20Search%20AutoPager.meta.js // ==/UserScript== var loadingBar = null, scrollTimeout = null, content_left = document.getElementById('content_left'), _pager = document.getElementById('page'), resultsLength = document.querySelectorAll('#content_left>div.c-container').length, queryString = (location.search.match(/wd=[^&]+/) || [''])[0], pageNum = Math.floor(((location.search.match(/&pn=(\d+)/) || [0, 0])[1] - 0) / resultsLength), //初始页码 imagesList = [], isLastPage = !_pager.lastElementChild || _pager.lastElementChild.localName === 'strong', container = null, tipsContainer = null; var cE = function(name, attr, parent){ var e = document.createElement(name); for (var i in attr || []) i == 'text' ? (e.textContent = attr[i]) : e.setAttribute(i, attr[i]); parent && (Array.isArray(parent) ? parent[0].insertBefore(e, parent.length == 2 ? parent[1] : parent[0].firstChild) : parent.appendChild(e)); return e; }, addPreviews = function(list){ [].forEach.call(list, function(div){ var cite = div.querySelector('cite, .g, .c-showurl'); if(!cite) return; var match = cite.textContent.trim().replace(/\.+$/, '').match(/(https?:\/\/)?([^/]+)/); match && match[2].length > 1 && imagesList.push(cE('img', {align: 'left', 'pic-src': 'https://'+ match[2].charAt(0) + '.searchpreview.de/preview?s='+ (match[1] || 'http://') + match[2] +'&ra=0'}, [div])); }); }, toggleLoadingBar = function(show){ (loadingBar || (loadingBar = cE('div', {id:'loadingBar'}, [document.getElementById('foot')]))) .classList[show ? 'add' : 'remove']('loading'); }, getNextPageData = function(url, callback){ var req = new XMLHttpRequest(); req.open('GET', url, true); req.send(); req.onload = function(){ callback((new DOMParser()).parseFromString(req.responseText, 'text/html')); }; }, nextPage = function(){ toggleLoadingBar(true); var url = 's?tn=monline_dg&pn='+ ((pageNum + 1) * resultsLength) + '&' + queryString; getNextPageData(url, function(doc){ //修复自动翻页后图片盒子 var imageBox, dScript; if((imageBox = doc.querySelector('.c-border')) && (dScript = imageBox.querySelector('script[data-compress]')) ){try{ imagesBoxFix(doc, JSON.parse(dScript.textContent .match(/{([^{}]|{[^{}]*})*}/)[0].replace(/\'/g, '"'))); }catch(ex){}} var df = document.createDocumentFragment(), last = content_left.children[content_left.children.length - 1]; [].forEach.call(doc.querySelectorAll('#content_left>div.c-container'), df.appendChild.bind(df)); //添加预览图 addPreviews(df.children); //往最后结果后面插入 last.parentNode.insertBefore(df, last.nextElementSibling); //替换新页码 var pageNumMenu = doc.getElementById('page'), _pageNumMenu = document.getElementById('page'); _pageNumMenu.parentNode.replaceChild(pageNumMenu, _pageNumMenu); //更新地址 history.pushState({}, doc.title, url); toggleLoadingBar(); onScroll(); resetMouseEvent(); if(!pageNumMenu.lastElementChild || pageNumMenu.lastElementChild.localName === 'strong') return (isLastPage = true) && !imagesList.length && removeEventListener('scroll', onScroll); //图片都加载完成 最后一页 else isLastPage = false; pageNum++; }); }, onResize = function(){ var content_right = document.getElementById('content_right'), //右侧栏高度 div_ch = 0; //第一页搜索项累计高 onScroll(); if(!content_right) return; [].forEach.call(content_left.children, function(div){ div.style.width = (div_ch < content_right.clientHeight) ? 'calc(98% - '+ content_right.clientWidth +'px)' : '100%'; div_ch += div.clientHeight; }); }, onScroll = function(){ clearTimeout(scrollTimeout); scrollTimeout = setTimeout(function(){ isLastPage && !imagesList.length && removeEventListener('scroll', onScroll); var de = document.documentElement; if(!de.scrollTop) de = document.body;//兼容chrome if(!isLastPage && de.scrollTop + window.innerHeight > de.scrollHeight - 5){ nextPage(); }else{ clearTimeout(scrollTimeout); } //lazyload var loadedList = []; imagesList.forEach(function(img){ var r = img.getBoundingClientRect(); if(r.bottom >= 0 && window.innerHeight >= r.top){ loadedList.push(img); img.parentNode.classList.add('loading'); img._loadCount = 0; img.onload = function(){ this.parentNode.classList.remove('loading'); this.onload = this.onerror = null; }; //首字母递增重试5次 img.onerror = function(){ this._loadCount++; if(this._loadCount > 4) return this.onload(); this.src = this.src.replace(/.(?=\.)/, function(s){ return String.fromCharCode((((s = s.charCodeAt()) >= 48 && s < 57) || (s >= 97 && s < 122)) ? s + 1 : (s == 57 ? 97 : 48)); }); }; img.src = img.getAttribute('pic-src'); img.removeAttribute('pic-src'); } }); loadedList.forEach(function(img){ imagesList.splice(imagesList.indexOf(img), 1); }); }, 500); }, resetMouseEvent = function(e){ //重置翻页后某些鼠标事件 (container || (container = window.$('#container'))) .undelegate('.c-tools', 'mouseover').undelegate('.c-tools', 'mouseout'); (tipsContainer || (tipsContainer = window.$('#c-tips-container'))) .undelegate('.c-tip-con', 'mouseover').undelegate('.c-tip-con', 'mouseout'); with(window) bds && bds.se && bds.se.tools && bds.se.tools(); //vip评级按钮 if(!e) with(window) bds && bds.se && bds.se.trust && bds.se.trust.init(); }, imagesBoxFix = function (doc, iamgesDate) { //修复自动翻页后图片盒子 var pageSize = 8, pager = doc.querySelector('.op_jingyan_pager'), showmore = doc.querySelector('.op_jingyan_list_showmore'), hiedmore = doc.querySelector('.op_jingyan_list_hide'), list1 = doc.querySelector('.op_jingyan_list1'), list2 = doc.querySelector('.op_jingyan_list2'), currentPage = 1, count = iamgesDate.images.length, pageCount = Math.ceil(count / pageSize); var show = function(element){ if(element) element.style.display = 'block'; }, hide = function(element){ if(element) element.style.display = 'none'; }; showmore.firstElementChild.onclick = function () { show(list2), show(hiedmore), show(pager), hide(showmore); }, hiedmore.firstElementChild.onclick = function () { hide(list2), hide(hiedmore), hide(pager), show(showmore), currentPage = 1, renderRow(1), renderPager() }; var renderPager = function () { var count = pageCount; if (!(count < 1)) { var html = [], shown = {}, draw = function (index) { if (shown[index]) return ''; if (shown[index] = true, index == currentPage) return '' + currentPage + ''; else return '' + index + '' }; if (currentPage > 1) html.push('上一页'); var point = currentPage; if (count - 2 < point) point = count - 2; if (point < 5) if (count < 5) point = count; else point = 5; if (point > 5) html.push(draw(1)), html.push('...'), html.push(draw(point - 2)), html.push(draw(point - 1)); else for (var i = 1; i < point; i++) html.push(draw(i)); if (html.push(draw(point)), point = currentPage, point < 3) point = 3; if (count - point < 4) if (point = count - 2, point < 1) point = 1; if (count - point > 4) html.push(draw(point + 1)), html.push(draw(point + 2)), html.push('...'), html.push(draw(count)); else for (var i = point; i <= count; i++) html.push(draw(i)); if (currentPage < count) html.push('下一页'); if(pager){ pager.innerHTML = html.join(''); var items = pager.querySelectorAll('.op_jingyan_pager_item'); [].forEach.call(items, function (item) { var index = parseInt(item.getAttribute('data-page'), 10); item.onclick = function (e) { if(e.button !=0) return; renderRow(index); var oldPage = currentPage; currentPage = index, (pager.innerHTML = '加载中...'), renderPager() } }) } } }, renderRow = function (index) { index -= 1; for (var imgData = iamgesDate.images.slice(index * pageSize, index * pageSize + pageSize), list1Html = [], list2Html = [], i = 0; i < pageSize / 2; i++) if (imgData[i]) list1Html.push(renderCell(imgData[i], index * pageSize + i)); for (var i = pageSize / 2; i <= pageSize; i++) if (imgData[i]) list2Html.push(renderCell(imgData[i], index * pageSize + i)); (list1.innerHTML = list1Html.join('')), (list2.innerHTML= list2Html.join('')) }, renderCell = function (data, index) { var cellHtml = []; if (3 === index % (pageSize / 2)) cellHtml.push('
' + data.imgtext + '
'); if (data.imglinkurl) cellHtml.push(''); return cellHtml.push('' + (parseInt(index, 10) + 1) + ''), cellHtml.push('