您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
1. 绅士漫画,下拉浏览页面,由原先的一列模式改为两列模式 2. javbus, 添加 "粘贴并搜索" 按钮; 添加 "打开srbt" 链接; 详情页面添加复制车牌号按钮.
当前为
// ==UserScript== // @name tianteng // @namespace https://greasyfork.org/xmlspy // @version 0.5.0 // @description 1. 绅士漫画,下拉浏览页面,由原先的一列模式改为两列模式 2. javbus, 添加 "粘贴并搜索" 按钮; 添加 "打开srbt" 链接; 详情页面添加复制车牌号按钮. // @author xmlspy // @license MIT // @require https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js // @include * // @connect * // @run-at document-start // @grant GM_xmlhttpRequest // @grant GM.setClipboard // @grant GM.xmlhttpRequest // @grant unsafeWindow // @grant GM_log // @grant GM_info // ==/UserScript== (function () { "use strict"; const enableDebug = true; let seq = 0; ////////////////////////////////////////////////////////////////////////////////////////////// /////////////////// 事件拦截 ///////////////////////////////////////////////////////////////////////////////////////////// debug(document.querySelector("title")); //松鼠症倉庫 地址发布页 https://ahrilist.top/ const ep = EventTarget.prototype; if (ep.addEventListenerOriginal == null) { ep.addEventListenerOriginal = ep.addEventListener; function addEventListenerHook(type, callback, options) { // if (/ahri8\.top/.test(window.location.href)) { if (this.className && this.className.includes("apo")) { debug("松鼠症倉庫-禁止点击广告"); return; } // } this.allListeners = this.allListeners || []; this.allListeners.push({ type, callback, options }); this.addEventListenerOriginal(type, callback, options); } ep.addEventListener = addEventListenerHook; } const skrbtDomain = "skrbtqx"; const skrbtHost = skrbtDomain + ".top"; const skrbtUrl = "https://" + skrbtHost; // execute(()=>{},()=>{}); $(function () { // execute("松鼠症倉庫", /ahri8\.top/, () => { // removeEvents(document.querySelectorAll("a.apo"), "click"); // debug("-------------------------------------------------------xxxx"); // }); execute("开源中国", /oschina\.net(\/)?$/, () => { $("div.headline > div.head-news > div").each(function (index) { const $this = $(this); const href = $this.attr("data-href"); const classCss = $this.attr("class"); const title = $this.attr("title"); const html = `<a target="_blank" title="${title}" href="${href}" class="${classCss}">${title}</a>`; $this.replaceWith(html); }); }); ////////////////////////////////////////////////////////////////////////////////////////////// /////////////////// 紳士漫畫永久域名: wnacg.com 紳士漫畫永久地址發佈頁: wnacg.date ///////////////////////////////////////////////////////////////////////////////////////////// execute("紳士漫畫", '$head>title:contains("紳士漫畫")', () => { if (location.href.includes("photos-slide-aid")) { const nodeToObserve = document.querySelector("#img_list"); $(nodeToObserve).css({ width: "100%", display: "flex", "flex-wrap": "wrap", "justify-content": "flex-start", "overflow-x": "hidden", }); const imgWidth = document.documentElement.clientWidth / 2 - 10; const imgHeight = document.documentElement.clientHeight - 50; const observer = new MutationObserver((mutations, observer) => { $("#img_list>div").css({ flex: "1", "background-color": "#cacaca", margin: "0 5px 5px 0", width: "calc((100% - 10px) / 2)", "min-width": "calc((100% - 10px) / 2)", "max-width": "calc((100% - 10px) / 2)", }); $("#img_list>div>img").on("load", (e) => { drawImage(e.target, imgWidth, imgHeight); }); }); observer.observe(nodeToObserve, { childList: true }); } }); ////////////////////////////////////////////////////////////////////////////////////////////// // 永久域名:https://www.javbus.com 防屏蔽地址:https://www.fanbus.help // 防屏蔽地址:https://www.javsee.help 防屏蔽地址:https://www.buscdn.help ///////////////////////////////////////////////////////////////////////////////////////////// execute( "javbus", [ '$head>title:contains("JavBus")', // /genre/hd , /genre/sub "$body > nav > div > div.navbar-header.mh50 > a > img[alt='JavBus']", // 论坛 "#toptb.jav-nav", ], () => { const searchButton = $( "button[onclick=\"searchs('search-input')\"]:first" ); const searchInput = $("#search-input:first"); addPasteAndSearchButton(searchButton, searchInput); // 调整样式 $(".nav>li>a").attr("style", "padding-left:8px;padding-right:8px;"); //添加skrbt链接 $(".nav-title.nav-inactive:last,ul.nav.navbar-nav:first").append(` <li class="hidden-md hidden-sm"> <a href="${skrbtUrl}" target="_blank">打开skrbt</a> </li> `); let chePaiNode = document.querySelector( "body > div.container > div.row.movie > div.col-md-3.info > p:nth-child(1) > span:nth-child(2)" ); // 明细页面 if (chePaiNode) { const chePai = chePaiNode.innerText.trim(); const toAppendElement = document.querySelector( "body > div.container > div.row.movie > div.col-md-3.info > p:nth-child(1)" ); appendCopyButton(chePai, toAppendElement); // 删除磁力链接中的onclick事件 setInterval(() => $("#magnet-table td").removeAttr("onclick"), 1000); } } ); ////////////////////////////////////////////////////////////////////////////////////////////// /////////////////// 添加 粘贴&搜索 按钮 ///////////////////////////////////////////////////////////////////////////////////////////// [ // 知乎 { title: "知乎-添加'粘贴&搜索'按钮", condition: /zhihu\.com/, searchButton: '$button[class*="SearchBar-searchButton"]', searchInput: "#Popover1-toggle", }, // skrbt 永 久 地 址 ( 务 必 收 藏 ): skrfabu.top skrso.link { title: "skrbt-添加'粘贴&搜索'按钮", condition: `$head>link[rel='shortcut icon'][href*='skrbt']`, searchButton: `$button.search-btn`, searchInput: `$input.search-input[name='keyword']`, }, // 百度 { title: "百度-添加'粘贴&搜索'按钮", condition: /baidu\.com/, searchButton: `#su`, searchInput: `#kw`, }, // 必应 // { // condition: /bing\.com/, // searchButton: ()=>{ // let inputs = document.querySelectorAll('input'); // return inputs[1]; // }, // searchInput: `#sb_form_q`, // }, ].forEach((v, k) => { let { title, condition, searchButton, searchInput, callback } = v; execute(title, condition, () => { searchButton = evalParam(searchButton); searchInput = evalParam(searchInput); addPasteAndSearchButton(searchButton, searchInput, callback); }); }); }); ////////////////////////////////////////////////////////////////////////////////////////////// /////////////////// 公共方法 ///////////////////////////////////////////////////////////////////////////////////////////// /** * * @param {String|Function} param * 当类型为String时, * - 如果param是以$开头,则认为这个param为Jquery表达式,会去掉字符$,并返回; * - 否则,认为param为常规css选择符,会返回document.querySelector(param) * 当类型为Function时, * 直接执行此方法,并使用$()包装并返回 * * @returns {Jquery} 返回Jquery对象 * * @example * - evalParam('$div[style="btn"]'); // param为jquery的css selector,返回$('div[style="btn"]') * - evalParam('#container'); // param为常规的css selector,返回 $(document.querySelecotr('#container')) * - evalParam(()=>{ * return document.querySelector('#container'); * }); // param为方法,返回$(param()) * */ function evalParam(param) { if ($.type(param) === "string") { if (param.startsWith("$")) { return $(param.substring(1)); } return $(document.querySelector(param)); } if ($.isFunction(param)) { return $(param()); } } function execute(title, condition, callback) { if (checkCondition(condition) === true) { if (callback) { debug(condition.toString(), title); callback(); } } // if ($.isArray(condition)) { // for (let c of condition) { // if (checkCondition(c)) { // debug(condition.toString(), title); // callback && callback(); // return; // } // } // } } /** * * @param {RegExp|Function|Boolean|String} condition * @returns {Boolean} */ function checkCondition(condition) { if ($.type(condition) === "regexp") { const href = window.location.href; return condition.test(href); } if ($.isFunction(condition)) { return condition() === true; } if ($.type(condition) === "boolean") { return condition === true; } if ($.type(condition) === "string") { if (condition.startsWith("$")) { return $(condition.substring(1)).length > 0; } return document.querySelector(condition) != null; } if ($.isArray(condition)) { for (let c of condition) { if (checkCondition(c)) { return true; } } } return false; } function addPasteAndSearchButton($searchButton, $searchInput, callback) { const styleMap = {}; $searchButton[0].computedStyleMap().forEach((value, key) => { styleMap[key] = value; }); const $pasteAndSearchButton = $( `<input type="button" value="粘贴&搜索" id="pasteAndSearch"></input>` ); $pasteAndSearchButton.css(styleMap); $searchButton.after($pasteAndSearchButton); $pasteAndSearchButton.click(() => { navigator.clipboard.readText().then((clipText) => { if (clipText != null && $.trim(clipText) != "") { $searchInput.val($.trim(clipText)); $searchButton.click(); } }); }); callback && callback($searchButton, $searchInput, $pasteAndSearchButton); } function appendCopyButton(chePai, toAppendElement) { var copyButton = document.createElement("button"); copyButton.innerHTML = "复 制"; copyButton.setAttribute("id", "copyButton"); toAppendElement.appendChild(copyButton); document.addEventListener("click", (e) => { if (e.target.getAttribute("id") === "copyButton") { GM.setClipboard(chePai, "text"); } }); } function debug(str, title) { if (enableDebug) { if (!str) { str = ""; } if (!Array.isArray(str)) { str = [str]; } seq++; console.log( `%c【tianteng ${GM_info.script.version}】 ${title ? title : "debug"}:`, "color: yellow;font-size: large;font-weight: bold;background-color: darkblue;", seq, ...str ); } } /** * 图片按宽高比例进行自动缩放 * @param ImgObj * 缩放图片源对象 * @param maxWidth * 允许缩放的最大宽度 * @param maxHeight * 允许缩放的最大高度 * @usage * 调用:<img src="图片" onload="javascript:drawImage(this,300,200)"> */ function drawImage(ImgObj, maxWidth, maxHeight) { var image = new Image(); //原图片原始地址(用于获取原图片的真实宽高,当<img>标签指定了宽、高时不受影响) image.src = ImgObj.src; // 用于设定图片的宽度和高度 var tempWidth; var tempHeight; if (image.width > 0 && image.height > 0) { //原图片宽高比例 大于 指定的宽高比例,这就说明了原图片的宽度必然 > 高度 if (image.width / image.height >= maxWidth / maxHeight) { if (image.width > maxWidth) { tempWidth = maxWidth; // 按原图片的比例进行缩放 tempHeight = (image.height * maxWidth) / image.width; } else { // 按原图片的大小进行缩放 tempWidth = image.width; tempHeight = image.height; } } else { // 原图片的高度必然 > 宽度 if (image.height > maxHeight) { tempHeight = maxHeight; // 按原图片的比例进行缩放 tempWidth = (image.width * maxHeight) / image.height; } else { // 按原图片的大小进行缩放 tempWidth = image.width; tempHeight = image.height; } } // 设置页面图片的宽和高 ImgObj.height = tempHeight; ImgObj.width = tempWidth; // 提示图片的原来大小 ImgObj.alt = image.width + "×" + image.height; } } /** * * @param {EventTarget|NodeList|Array|jQuery} elements * @param {undefined|null|String|Array} events */ function removeEvents(elements, events) { if (!elements) return; if (elements instanceof EventTarget) { elements = [elements]; } if (elements instanceof jQuery) { elements = elements.toArray(); } if (!events) { elements.forEach((element) => { for (let t in element) { if (t.startsWith("on") && element[t] != null) { element[t] = null; console.log("cleanup removed listener from " + element.nodeName, t); } } for (let t of element.allListeners || []) { element.removeEventListener(t.type, t.callback, t.options); console.log( "cleanup removed listener from " + element.nodeName, t.type ); } element.allListeners = []; }); } else { if (typeof events === "string") { events = [events]; } if (!Array.isArray(events)) { return; } events.forEach((event) => { const onEvent = "on" + event; elements.forEach((element) => { for (let t in element) { if (t.startsWith(onEvent) && element[t] != null) { element[t] = null; console.log( "cleanup removed listener from " + element.nodeName, t ); } } // const toRemoved = []; element.allListeners = element.allListeners || []; let allListenersNew; element.allListeners.forEach((t, i) => { if (t.type === event) { element.removeEventListener(t.type, t.callback, t.options); allListenersNew = element.allListeners.slice(i, 1); // toRemoved.push(i); console.log( "cleanup removed listener from " + element.nodeName, t.type ); } }); // toRemoved.forEach((item, index) => { // element.allListeners = element.allListeners.slice(item, 1); // }); if (allListenersNew) { element.allListeners = allListenersNew; } }); }); } } })();