您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Navigate through websites using keyboard buttons N/B for next/previous pages.
// ==UserScript== // @name Navigational Keyboard Shortcuts // @namespace https://github.com/kittenparry/ // @version 1.27.1 // @description Navigate through websites using keyboard buttons N/B for next/previous pages. // @author kittenparry // @match *://*/* // @grant none // @license GPL-3.0-or-later // ==/UserScript== /* LIST: * archived.moe * google.com * imgfrog.pw * metal-tracker.com * mods.factorio.com * nexusmods.com * nyaa.si * opengameart.org * rarbg.to || rarbgproxy.org || rarbg2020.org || rarbgget.org * reddit.com * stargate.fandom.com * steamcommunity.com/workshop/ * steamgifts.com * trakt.tv * tumblr.com * xkcd.com * NSFW: * 420chan.org * 8muses.com * *.booru.org * camshowhub.to * camvault.xyz * camwhores.tv * chaturbate.com * coedcherry.com * erome.com * f95zone.com * forum.sexy-egirls.com * forum.thotsbay.com * forums.sexy-youtubers.com * forums.socialmediagirls.com * hanime.tv * hentai-foundry.com * hongfire.com * javbus.com * kitty-kats.net * loverslab.com * meitulu.com * meituri.com * nhentai.net * nobodyhome.tv * pixietrixcomix.com * planetsuzy.org * pornbay.org * pornhub.com * recurbate.com * rec-tube.com * shadbase.com * simpcity.su * sinnercomics.com * thothub.tv * totempole666.com * xbunker.nu * xbunker.su * yiff.party/activity */ /* CHANGELOG: * 1.27.1: +xbunker.nu (xbunker.su alt/ rather updated domain) * 1.27: +xbunker.su +simpcity.su +forums.socialmediagirls.com * 1.26.1: +rarbgget.org (rarbg.to alt) * 1.26: +forum.thotsbay.com * 1.25: +opengameart.org * 1.24: +rarbg2020.org (rarbg.to alt) +xkcd.com +pixietrixcomix.com * 1.23: +forums.sexy-youtubers.com +forum.sexy-egirls.com * 1.22: +420chan.org * 1.21: +totempole666.com * 1.20.1: fix archived.moe first (& likely last) page navigation * 1.20: +loverslab.com | could probably be better with a special of its own similar to nexusmods * 1.19: +pornhub.com * 1.18: +google.com * 1.17: +archived.moe * 1.16: +kitty-kats.net * 1.15: +mods.factorio.com * 1.14: +imgfrog.pw * 1.13.1: lack of special handling similar to focus_input_key script (fik.user.js) * 1.13: +*.booru.org * 1.12: +camshowhub.to * 1.11.1: fix trakt.tv back keybind not working * 1.11: +stargate.fandom.com | navigates the episodes (preceded by & followed by) * 1.10: +trakt.tv +camvault.xyz | trakt.tv only works in episode/season views * 1.9.2: additional functions to ease repetition & meituri/meitulu isn't special anymore * 1.9.1: ability to navigate to first/last pages on pornbay.org * 1.9: +rec-tube.com * 1.8: +erome.com +recurbate.com +hanime.tv * 1.7.1: +nobodyhome.tv instead of nobodyhome.ga (domain change) * 1.7: +planetsuzy.org * 1.6.1: +rarbgproxy.org as an alternative to rarbg.to * 1.6: +chaturbate.com * 1.5: +meituri.com +meitulu.com | they work the same way so a simple or will do * 1.4: +javbus.com | switch to semantic versioning so incrementing minor instead of patch part (https://semver.org/) * 1.3.7: +thothub.tv * 1.3.6: +nexusmods.com | a special case similar to camwhores.tv * 1.3.5: +yiff.party/activity | with some clunky mechanics * 1.3.4: +steamcommunity.com/workshop/ * 1.3.3: +f95zone.to/latest/ | change the original link to .to as well * 1.3.2: +metal-tracker.com | btn case i wanted to use in camwhores.tv * 1.3.1: +shadbase.com * 1.3: +camwhores.tv | element needs to be reassigned each time so it's in the function * 1.2.4: +8muses.com * 1.2.3: +nobodyhome.ga * 1.2.2: +hongfire.com * 1.2.1: prevent execution of code when not on these sites * 1.2: +f95zone.com * 1.1: +nyaa.si +coedcherry.com * 1.0: initial | rarbg.com reddit.com steamgifts.com tumblr.com * & hentai-foundry.com nhentai.net pornbay.org sinnercomics.com */ check_nav_key_press = (e, prev, next, special) => { var type = e.target.getAttribute('type'); var tag = e.target.tagName.toLowerCase(); if (type != 'text' && tag != 'textarea' && type != 'search') { if (e.keyCode == 66) { if (special == 'camwhores') { document.querySelector('li[class="page-current"]').previousElementSibling.firstElementChild.click(); } else if (special == 'nexusmods') { document.querySelector('li[class="prev"]').firstElementChild.click(); } else if (special == 'hanime') { sel_and_click('.pagination__navigation', 0); } else if (special == 'btn' && prev != undefined) { document.querySelector(prev).click(); } else if (special == 'url' && prev != undefined) { window.location = prev; } else if (special == '') { window.location = get_query_href(prev); } } else if (e.keyCode == 78) { if (special == 'camwhores') { document.querySelector('li[class="page-current"]').nextElementSibling.firstElementChild.click(); } else if (special == 'nexusmods') { document.querySelector('li[class="next"]').firstElementChild.click(); } else if (special == 'hanime') { sel_and_click('.pagination__navigation', 3); } else if (special == 'btn' && next != undefined) { document.querySelector(next).click(); } else if (special == 'url' && next != undefined) { window.location = next; } else if (special == '') { window.location = get_query_href(next); } } } }; // return the first result of a given tag with the text // eg. ('a', 'prev') returns the anchor with 'prev' innerHTML find_els_with_text = (tag, text) => { var els = document.getElementsByTagName(tag); var found = []; for (var i = 0; i < els.length; i++) { if (els[i].innerHTML == text) { found.push(els[i]); } } return found[0].href; }; // return the href of given selector get_query_href = (sel) => { return document.querySelector(sel).href; }; // click the idxth element of given selector sel_and_click = (sel, idx) => { document.querySelectorAll(sel)[idx].click(); }; // return the href of given selector at idxth get_sel_href = (sel, idx) => { return document.querySelectorAll(sel)[idx].href; }; /* probably need a better way than simply .includes() * pqsel: previous query selector * nqsel: next query selector * nav_spcl: used when url is given instead of selector * check steamgifts example * also these include try/catch if they don't exist yet (first/last page) * !this section really looks ugly and repetitive */ var cur_loc = window.location.href; if (cur_loc.includes('archived.moe')) { var nav_spcl = 'url'; try { var pqsel = document.querySelector('li[class="prev"]').firstElementChild.href; } catch (e) {} try { var nqsel = document.querySelector('li[class="next"]').firstElementChild.href; } catch (e) {} } else if (cur_loc.includes('google.com')) { var nav_spcl = 'url'; try { var nqsel = get_sel_href('.pn', 1); } catch (e) { // if the first page var nqsel = get_sel_href('.pn', 0); } try { var pqsel = get_sel_href('.pn', 0); // if the first page if (nqsel == pqsel) { pqsel = null; } } catch (e) {} } else if (cur_loc.includes('imgfrog.pw')) { var pqsel = 'a[data-pagination="prev"]'; var nqsel = 'a[data-pagination="next"]'; } else if (cur_loc.includes('metal-tracker.com')) { var nav_spcl = 'btn'; var pqsel = 'li[class="previous"]'; var nqsel = 'li[class="next"]'; } else if (cur_loc.includes('mods.factorio.com')) { var nav_spcl = 'url'; try { var pqsel = find_els_with_text('a', '« Previous'); } catch (e) {} try { var nqsel = find_els_with_text('a', 'Next »'); } catch (e) {} } else if (cur_loc.includes('nexusmods.com')) { var nav_spcl = 'nexusmods'; var pqsel = ''; var nqsel = ''; } else if (cur_loc.includes('nyaa.si')) { var pqsel = 'a[rel="prev"]'; var nqsel = 'a[rel="next"]'; } else if (cur_loc.includes('opengameart.org')) { var pqsel = 'a[title="Go to previous page"]'; var nqsel = 'a[title="Go to next page"]'; } else if (cur_loc.includes('rarbg.to') || cur_loc.includes('rarbgproxy.org') || (cur_loc.includes('rarbg2020.org')) || (cur_loc.includes('rarbgget.org'))) { var pqsel = 'a[title="previous page"]'; var nqsel = 'a[title="next page"]' } else if (cur_loc.includes('reddit.com')) { var pqsel = 'a[rel="nofollow prev"]'; var nqsel = 'a[rel="nofollow next"]'; } else if (cur_loc.includes('stargate.fandom.com')) { var nav_spcl = 'url'; try { var pqsel = document.querySelector('div[data-source="preceded_by"]').lastElementChild.firstElementChild.href; } catch (e) {} try { var nqsel = document.querySelector('div[data-source="followed_by"]').lastElementChild.firstElementChild.href; } catch (e) {} } else if (cur_loc.includes('steamcommunity.com/workshop/')) { var nav_spcl = 'url'; try { var pqsel = get_sel_href('.pagebtn', 0); } catch (e) {} try { var nqsel = get_sel_href('.pagebtn', 1); } catch (e) {} } else if (cur_loc.includes('steamgifts.com')) { var nav_spcl = 'url'; try { var pqsel = document.querySelector('i[class="fa fa-angle-left"]').parentNode.href; } catch (e) {} try { var nqsel = document.querySelector('i[class="fa fa-angle-right"]').parentNode.href; } catch (e) {} } else if (cur_loc.includes('trakt.tv')) { var pqsel = 'a[rel="prev"]'; var nqsel = 'a[rel="next"]'; } else if (cur_loc.includes('tumblr.com')) { var pqsel = 'a[id="previous_page_link"]'; var nqsel = 'a[id="next_page_link"]'; } else if (cur_loc.includes('xkcd.com')) { var pqsel = 'a[rel="prev"]'; var nqsel = 'a[rel="next"]'; /* * * * * * * * * * * * * * * * * NSFW BELOW * * * * * * * * * * * * * * * * */ } else if (cur_loc.includes('420chan.org')) { var nav_spcl = 'url'; try { var pqsel = find_els_with_text('a', '« Previous'); } catch (e) {} try { var nqsel = find_els_with_text('a', 'Next »'); } catch (e) {} } else if (cur_loc.includes('8muses.com')) { var pqsel = 'a[class="pageNav-jump pageNav-jump--prev"]'; var nqsel = 'a[class="pageNav-jump pageNav-jump--next"]'; } else if (cur_loc.includes('.booru.org')) { var pqsel = 'a[alt="back"]'; var nqsel = 'a[alt="next"]'; } else if (cur_loc.includes('camshowhub.to')) { var pqsel = 'a[title="Previous page"]'; var nqsel = 'a[title="Next page"]'; } else if (cur_loc.includes('camvault.xyz')) { var pqsel = 'a[rel="prev"]'; var nqsel = 'a[rel="next"]'; } else if (cur_loc.includes('camwhores.tv')) { var nav_spcl = 'camwhores'; var pqsel = ''; var nqsel = ''; } else if (cur_loc.includes('chaturbate.com')) { var pqsel = 'a[class="prev endless_page_link"]'; var nqsel = 'a[class="next endless_page_link"]'; } else if (cur_loc.includes('coedcherry.com')) { var pqsel = 'a[rel="prev"]'; var nqsel = 'a[rel="next"]'; } else if (cur_loc.includes('erome.com')) { var pqsel = 'a[rel="prev"]'; var nqsel = 'a[rel="next"]'; } else if (cur_loc.includes('f95zone.to/latest/')) { // something else for "/pages/latest/" var pqsel = 'a[class="nav_prev"]'; var nqsel = 'a[class="nav_next"]'; } else if (cur_loc.includes('f95zone.to')) { // for only threads/forums // something else is required for /pages/latest/ var pqsel = 'a[class="pageNav-jump pageNav-jump--prev"]'; var nqsel = 'a[class="pageNav-jump pageNav-jump--next"]'; } else if (cur_loc.includes('hanime.tv')) { var nav_spcl = 'hanime' var pqsel = ''; var nqsel = ''; } else if (cur_loc.includes('hentai-foundry.com')) { var nav_spcl = 'url'; try { var pqsel = document.querySelector('li[class="previous"]').firstChild.href; } catch (e) {} try { var nqsel = document.querySelector('li[class="next"]').firstChild.href; } catch (e) {} } else if (cur_loc.includes('hongfire.com')) { var pqsel = 'a[class="js-pagenav-button js-pagenav-prev-button b-button b-button--secondary js-shrink-event-child"]'; var nqsel = 'a[class="js-pagenav-button js-pagenav-next-button b-button b-button--secondary js-shrink-event-child"]'; } else if (cur_loc.includes('javbus.com')) { var pqsel = 'a[id="pre"]'; var nqsel = 'a[id="next"]'; } else if (cur_loc.includes('kitty-kats.net')) { var pqsel = 'a[class="pageNav-jump pageNav-jump--prev"]'; var nqsel = 'a[class="pageNav-jump pageNav-jump--next"]'; } else if (cur_loc.includes('loverslab.com')) { var pqsel = 'a[rel="prev"]'; var nqsel = 'a[rel="next"]'; } else if (cur_loc.includes('meituri.com') || cur_loc.includes('meitulu.com')) { var nav_spcl = 'url'; try { var pqsel = get_sel_href('.a1', 0); } catch (e) {} try { var nqsel = get_sel_href('.a1', 1); } catch (e) {} } else if (cur_loc.includes('nhentai.net')) { var pqsel = 'a[class="previous"]'; var nqsel = 'a[class="next"]'; } else if (cur_loc.includes('nobodyhome.tv')) { var pqsel = 'a[class="pagination_previous"]'; var nqsel = 'a[class="pagination_next"]'; } else if (cur_loc.includes('pixietrixcomix.com')) { var pqsel = 'a[rel="prev"]'; var nqsel = 'a[rel="next"]'; } else if (cur_loc.includes('planetsuzy.org')) { var pqsel = 'a[rel="prev"]'; var nqsel = 'a[rel="next"]'; } else if (cur_loc.includes('pornbay.org')) { var nav_spcl = 'url'; try { try { var pqsel = get_query_href('a[class="pager pager_prev"]'); } catch (e) { var pqsel = get_query_href('a[class="pager pager_first"]'); } } catch (e) {} try { try { var nqsel = get_query_href('a[class="pager pager_next"]'); } catch (e) { var nqsel = get_query_href('a[class="pager pager_last"]'); } } catch (e) {} } else if (cur_loc.includes('pornhub.com')) { var nav_spcl = 'url'; try { var pqsel = document.querySelector('li[class="page_previous alpha"]').firstElementChild.href; } catch (e) {} try { var nqsel = document.querySelector('li[class="page_next omega"]').firstElementChild.href; } catch (e) {} } else if (cur_loc.includes('recurbate.com')) { var pqsel = 'a[aria-label="Previous"]'; var nqsel = 'a[aria-label="Next"]'; } else if (cur_loc.includes('rec-tube.com')) { var nav_spcl = 'url'; try { try { var pqsel = find_els_with_text('a', 'Prev Page'); } catch (e) { var pqsel = find_els_with_text('a', 'First Page') } } catch (e) {} try { try { var nqsel = find_els_with_text('a', 'Next Page'); } catch (e) { var nqsel = find_els_with_text('a', 'Last Page') } } catch (e) {} } else if (cur_loc.includes('shadbase.com')) { var pqsel = 'a[class="navi navi-prev"]'; var nqsel = 'a[class="navi navi-next"]'; } else if (cur_loc.includes('sinnercomics.com')) { var pqsel = 'a[class="comic-nav-base comic-nav-previous"]'; var nqsel = 'a[class="comic-nav-base comic-nav-next"]'; } else if (cur_loc.includes('thothub.tv') || cur_loc.includes('forums.sexy-youtubers.com') || cur_loc.includes('forum.sexy-egirls.com') || cur_loc.includes('forum.thotsbay.com') || cur_loc.includes('xbunker.su') || cur_loc.includes('simpcity.su') || cur_loc.includes('forums.socialmediagirls.com') || cur_loc.includes('xbunker.nu')) { var pqsel = 'a[class="pageNav-jump pageNav-jump--prev"]'; var nqsel = 'a[class="pageNav-jump pageNav-jump--next"]'; } else if (cur_loc.includes('totempole666.com')) { var pqsel = 'a[class="navi comic-nav-previous navi-prev"]'; var nqsel = 'a[class="navi comic-nav-next navi-next"]'; } else if (cur_loc.includes('yiff.party/activity')) { var nav_spcl = 'url'; try { var pqsel = find_els_with_text('a', 'prev'); } catch (e) {} try { var nqsel = find_els_with_text('a', 'next'); } catch (e) {} } if (pqsel != undefined || nqsel != undefined) { try { if (!nav_spcl) { var nav_spcl = ''; } window.addEventListener('keydown', (e) => check_nav_key_press(e, pqsel, nqsel, nav_spcl), false); } catch (e) {} }