您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
ニコニコ生放送の検索結果と「放送中の番組」ページにおいて、ページ送りボタンを上部にも表示 / Also shows the pagination on the top of Nico Live search result and Lives by Category page.
当前为
// ==UserScript== // @name Clone Turning Page Button in nicovideo // @namespace http://pc12.2ch.net/test/read.cgi/streaming/1275642556/ // @version 3.3.1 // @description ニコニコ生放送の検索結果と「放送中の番組」ページにおいて、ページ送りボタンを上部にも表示 / Also shows the pagination on the top of Nico Live search result and Lives by Category page. // @match http://live.nicovideo.jp/search?* // @match http://live.nicovideo.jp/recent // @match http://live.nicovideo.jp/recent?* // @match http://live.nicovideo.jp/recent#* // @match http://watch.live.nicovideo.jp/search?* // @match http://watch.live.nicovideo.jp/recent // @match http://watch.live.nicovideo.jp/recent?* // @match http://watch.live.nicovideo.jp/recent#* // @run-at document-start // @grant dummy // @icon data:image/vnd.microsoft.icon;base64,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 // @author 100の人 // @homepage https://greasyfork.org/ja/scripts/275-clone-turning-page-button-in-nicovideo // @license Creative Commons Attribution 4.0 International Public License; http://creativecommons.org/licenses/by/4.0/ // ==/UserScript== (function () { 'use strict'; switch (location.pathname) { case '/search': // ニコニコ生放送 検索結果 startScript(function () { var pager = document.getElementsByClassName('pager')[0]; if (pager) { // 41件以上ヒットしていれば // スタイルシートの設定 document.head.insertAdjacentHTML('beforeend', '<style> \ .result_list { \ border-top: 1px solid #888888; \ } \ </style>'); // 数字リンクの複製 var ref = document.getElementsByClassName('result_list')[0]; ref.parentElement.insertBefore(pager.cloneNode(true), ref); } }, function (parent) { return parent.classList.contains('container'); }, function (target) { return target.id === 'search_right'; }, function () { return document.getElementById('search_right'); }); break; case '/recent': // ニコニコ生放送 放送中の番組 startScript(function () { var parent = document.getElementById('onair_stream_list'); clonePager(); var observer = new MutationObserver(function (mutations) { if (mutations[0].addedNodes.length > 1) { // 数字リンクの複製でなければ clonePager(); } }); observer.observe(parent, { childList: true, }); function clonePager() { parent.insertBefore(document.getElementById('pagerFrame').cloneNode(true), document.getElementById('userFrame')); } }, function (parent) { return parent.id === 'left'; }, function (target) { return target.id === 'pickupFrame'; }, function () { return document.getElementById('pickupFrame'); }); break; } /** * 挿入された節の親節が、目印となる節の親節か否かを返すコールバック関数。 * @callback isTargetParent * @param {(Document|Element)} parent * @returns {boolean} */ /** * 挿入された節が、目印となる節か否かを返すコールバック関数。 * @callback isTarget * @param {(DocumentType|Element)} target * @returns {boolean} */ /** * 目印となる節が文書に存在するか否かを返すコールバック関数。 * @callback existsTarget * @returns {boolean} */ /** * 目印となる節が挿入された直後に関数を実行する。 * @param {Function} main - 実行する関数。 * @param {isTargetParent} isTargetParent * @param {isTarget} isTarget * @param {existsTarget} existsTarget * @param {Object} [callbacksForFirefox] * @param {isTargetParent} [callbacksForFirefox.isTargetParent] - Firefoxにおける{@link isTargetParent}。 * @param {isTarget} [callbacksForFirefox.isTarget] - Firefoxにおける{@link isTarget}。 * @param {boolean} [timeoutSinceStopParsingDocument=0] - DOM構築完了後に監視を続けるミリ秒数。 * @version 2014-09-04 */ function startScript(main, isTargetParent, isTarget, existsTarget) { /** * {@link checkExistingTarget}で{@link startMain}を実行する間隔(ミリ秒)。 * @constant {number} */ var INTERVAL = 10; /** * {@link checkExistingTarget}で{@link startMain}を実行する回数。 * @constant {number} */ var LIMIT = 500; /** * 実行済みなら真。 * @type {boolean} */ var alreadyCalled = false; // 指定した節が既に存在していれば、即実行 startMain(); if (alreadyCalled) { return; } // FirefoxのMutationObserverは、HTMLのDOM構築に関して要素をまとめて挿入したと見なすため、isTargetParent、isTargetを変更 var callbacksForFirefox = arguments[4]; if (callbacksForFirefox && typeof MozSettingsEvent !== 'undefined') { isTargetParent = callbacksForFirefox.isTargetParent || isTargetParent; isTarget = callbacksForFirefox.isTarget || isTarget; } var observer = new MutationObserver(mutationCallback); observer.observe(document, { childList: true, subtree: true, }); var timeoutSinceStopParsingDocument = arguments[5] || 0; if (document.readyState === 'complete') { // DOMの構築が完了していれば onDOMContentLoaded(); } else { document.addEventListener('DOMContentLoaded', onDOMContentLoaded); } /** * {@link startMain}を実行し、スクリプトが開始されていなければさらに{@link timeoutSinceStopParsingDocument}ミリ秒待機し、 * スクリプトが開始されていなければ{@link stopObserving}を実行する。 */ function onDOMContentLoaded() { startMain(); if (timeoutSinceStopParsingDocument === 0) { if (!alreadyCalled) { stopObserving(); } } else { window.setTimeout(function () { if (!alreadyCalled) { stopObserving(); } }, timeoutSinceStopParsingDocument); } } /** * 目印となる節が挿入されたら、監視を停止し、{@link checkExistingTarget}を実行する。 * @param {MutationRecord[]} mutations - A list of MutationRecord objects. * @param {MutationObserver} observer - The constructed MutationObserver object. */ function mutationCallback(mutations, observer) { var mutation, target, nodeType, addedNodes, addedNode, i, j, l, l2; for (i = 0, l = mutations.length; i < l; i++) { mutation = mutations[i]; target = mutation.target; nodeType = target.nodeType; if ((nodeType === Node.ELEMENT_NODE) && isTargetParent(target)) { // 子が追加された節が要素節で、かつその節についてisTargetParentが真を返せば addedNodes = Array.prototype.slice.call(mutation.addedNodes); for (j = 0, l2 = addedNodes.length; j < l2; j++) { addedNode = addedNodes[j]; nodeType = addedNode.nodeType; if ((nodeType === Node.ELEMENT_NODE) && isTarget(addedNode)) { // 追加された子が要素節で、かつその節についてisTargetが真を返せば observer.disconnect(); checkExistingTarget(0); return; } } } } } /** * {@link startMain}を実行し、スクリプトが開始されていなければ再度実行。 * @param {number} count - {@link startMain}を実行した回数。 */ function checkExistingTarget(count) { startMain(); if (!alreadyCalled && count < LIMIT) { window.setTimeout(checkExistingTarget, INTERVAL, count + 1); } } /** * 指定した節が存在するか確認し、存在すれば{@link stopObserving}を実行しスクリプトを開始。 */ function startMain() { if (!alreadyCalled && existsTarget()) { stopObserving(); main(); } } /** * 監視を停止する。 */ function stopObserving() { alreadyCalled = true; if (observer) { observer.disconnect(); } document.removeEventListener('DOMContentLoaded', onDOMContentLoaded); } } })();