PCのブラウザでカクヨム小説を読む人向けのキーボードでページめくりできるスクリプト

@PXXN3

PCのブラウザで小説を読む人向けのキーボードでページめくりできるスクリプト

カクヨムで小説を読むとき、前のエピソードや次のエピソードを見るには画面の先頭や末尾までスクロールしてクリックする必要があります。


これをいつでもワンキーでできるようにする魔法をこれから紹介します。


① Google Chrome や Firefox などのブラウザをお使いの方は、まず最初にスクリプト実行できる拡張機能を選んで有効にしてください。

JavaScript を inject 実行できる拡張機能ならなんでもよいです。

Chrome では Scripty や Script Runner Pro など、Firefox なら run-a-script や Injector などといったものが無数にあります。

使いやすく信頼できるものを選んでください。


② 次に以下のスクリプトをコピペして必要なサイトで自動で読み込むように設定してください。


ページめくりスクリプト

///////////////////////////////////////////////////ここから

(function () {

"use strict";

const list = [

{ url: 'kakuyomu.jp/works/',

code: 'ArrowLeft',

modifiers: '',

type: 'link',

link: 'prev',

},

{ url: 'kakuyomu.jp/works/',

code: 'NumpadSubtract',

modifiers: '',

type: 'link',

link: 'prev',

},

{ url: 'kakuyomu.jp/works/',

code: 'ArrowRight',

modifiers: '',

type: 'link',

link: 'next',

},

{ url: 'kakuyomu.jp/works/',

code: 'NumpadAdd',

modifiers: '',

type: 'link',

link: 'next',

},

{ url: 'kakuyomu.jp/works/',

code: 'Enter',

modifiers: '',

type: 'a',

link: '続きから読む',

},

{ url: 'kakuyomu.jp/works/',

code: 'NumpadEnter',

modifiers: '',

type: 'a',

link: '続きから読む',

},

{ url: 'kakuyomu.jp/',

code: 'BracketLeft',

modifiers: '',

type: 'url',

link: 'https://kakuyomu.jp/my',

},

{ url: 'kakuyomu.jp/',

code: 'Numpad3',

modifiers: '',

type: 'url',

link: 'https://kakuyomu.jp/my',

},

{ url: 'kakuyomu.jp/',

code: 'BracketRight',

modifiers: '',

type: 'url',

link: 'https://kakuyomu.jp/my/antenna/works',

},

{ url: 'kakuyomu.jp/',

code: 'Numpad2',

modifiers: '',

type: 'url',

link: 'https://kakuyomu.jp/my/antenna/works',

},

{ url: 'syosetu.com/',

code: 'ArrowLeft',

modifiers: '',

type: 'aclass',

link: 'c-pager__item--before',

},

{ url: 'syosetu.com/',

code: 'NumpadSubtract',

modifiers: '',

type: 'aclass',

link: 'c-pager__item--before',

},

{ url: 'syosetu.com/',

code: 'ArrowRight',

modifiers: '',

type: 'aclass',

link: 'c-pager__item--next',

},

{ url: 'syosetu.com/',

code: 'NumpadAdd',

modifiers: '',

type: 'aclass',

link: 'c-pager__item--next',

},

{ url: 'syosetu.com/favnovelmain',

code: 'ArrowLeft',

modifiers: '',

type: 'aclasstitle',

links: ['c-up-pager__item', '前'],

},

{ url: 'syosetu.com/favnovelmain',

code: 'NumpadSubtract',

modifiers: '',

type: 'aclasstitle',

links: ['c-up-pager__item', '前'],

},

{ url: 'syosetu.com/favnovelmain',

code: 'ArrowRight',

modifiers: '',

type: 'aclasstitle',

links: ['c-up-pager__item', '次'],

},

{ url: 'syosetu.com/favnovelmain',

code: 'NumpadAdd',

modifiers: '',

type: 'aclasstitle',

links: ['c-up-pager__item', '次'],

},

{ url: 'syosetu.com/impression/',

code: 'ArrowLeft',

modifiers: '',

type: 'atitle',

link: '前のページ',

},

{ url: 'syosetu.com/impression/',

code: 'NumpadSubtract',

modifiers: '',

type: 'atitle',

link: '前のページ',

},

{ url: 'syosetu.com/impression/',

code: 'ArrowRight',

modifiers: '',

type: 'atitle',

link: '次のページ',

},

{ url: 'syosetu.com/impression/',

code: 'NumpadAdd',

modifiers: '',

type: 'atitle',

link: '次のページ',

},

{ url: 'syosetu.com/impression/',

code: 'ArrowLeft',

modifiers: '+',

type: 'dec',

re: '\/no\/(\\d+)\/.*',

str: '/no/$$/',

},

{ url: 'syosetu.com/impression/',

code: 'NumpadSubtract',

modifiers: '+',

type: 'dec',

re: '\/no\/(\\d+)\/.*',

str: '/no/$$/',

},

{ url: 'syosetu.com/impression/',

code: 'ArrowRight',

modifiers: '+',

type: 'inc',

re: '\/no\/(\\d+)\/.*',

str: '/no/$$/',

},

{ url: 'syosetu.com/impression/',

code: 'NumpadAdd',

modifiers: '+',

type: 'inc',

re: '\/no\/(\\d+)\/.*',

str: '/no/$$/',

},

{ url: 'syosetu.com/',

code: 'Enter',

modifiers: '',

type: 'adivclass',

link: 'p-novel__bookmarker-no',

},

{ url: 'syosetu.com/',

code: 'NumpadEnter',

modifiers: '',

type: 'adivclass',

link: 'p-novel__bookmarker-no',

},

{ url: 'syosetu.com/',

code: 'Enter',

modifiers: '',

type: 'inputnameclick',

link: 'siori_url',

},

{ url: 'syosetu.com/',

code: 'NumpadEnter',

modifiers: '',

type: 'inputnameclick',

link: 'siori_url',

},

{ url: 'syosetu.com/',

code: 'BracketLeft',

modifiers: '',

type: 'url',

link: 'https://syosetu.com/user/top/',

},

{ url: 'syosetu.com/',

code: 'Numpad3',

modifiers: '',

type: 'url',

link: 'https://syosetu.com/user/top/',

},

{ url: 'syosetu.com/',

code: 'BracketLeft',

modifiers: '+',

type: 'url',

link: 'https://syosetu.com/xuser/top/',

},

{ url: 'syosetu.com/',

code: 'Numpad6',

modifiers: '',

type: 'url',

link: 'https://syosetu.com/xuser/top/',

},

{ url: 'syosetu.com/',

code: 'BracketRight',

modifiers: '',

type: 'url',

link: 'https://syosetu.com/favnovelmain/list/',

},

{ url: 'syosetu.com/',

code: 'Numpad2',

modifiers: '',

type: 'url',

link: 'https://syosetu.com/favnovelmain/list/',

},

{ url: 'syosetu.com/',

code: 'BracketRight',

modifiers: '+',

type: 'url',

link: 'https://syosetu.com/favnovelmain18/list/',

},

{ url: 'syosetu.com/',

code: 'Numpad5',

modifiers: '',

type: 'url',

link: 'https://syosetu.com/favnovelmain18/list/',

},

{ url: 'www.alphapolis.co.jp/novel/',

code: 'ArrowLeft',

modifiers: '',

type: 'a',

link: '前の話',

},

{ url: 'www.alphapolis.co.jp/novel/',

code: 'NumpadSubtract',

modifiers: '',

type: 'a',

link: '前の話',

},

{ url: 'www.alphapolis.co.jp/novel/',

code: 'ArrowRight',

modifiers: '',

type: 'a',

link: '次の話',

},

{ url: 'www.alphapolis.co.jp/novel/',

code: 'NumpadAdd',

modifiers: '',

type: 'a',

link: '次の話',

},

{ url: 'www.alphapolis.co.jp/novel/',

code: 'Enter',

modifiers: '',

type: 'a',

link: '続きから読む',

},

{ url: 'www.alphapolis.co.jp/novel/',

code: 'NumpadEnter',

modifiers: '',

type: 'a',

link: '続きから読む',

},

{ url: 'www.alphapolis.co.jp/novel/',

code: 'Enter',

modifiers: '',

type: 'spanclassesclick',

links: ['bookmark', 'enabled'],

},

{ url: 'www.alphapolis.co.jp/novel/',

code: 'NumpadEnter',

modifiers: '',

type: 'spanclassesclick',

links: ['bookmark', 'enabled'],

},

{ url: 'www.alphapolis.co.jp/',

code: 'BracketLeft',

modifiers: '',

type: 'url',

link: 'https://www.alphapolis.co.jp/mypage/content',

},

{ url: 'www.alphapolis.co.jp/',

code: 'Numpad3',

modifiers: '',

type: 'url',

link: 'https://www.alphapolis.co.jp/mypage/content',

},

{ url: 'www.alphapolis.co.jp/',

code: 'BracketRight',

modifiers: '',

type: 'url',

link: 'https://www.alphapolis.co.jp/mypage/favorite',

},

{ url: 'www.alphapolis.co.jp/',

code: 'Numpad2',

modifiers: '',

type: 'url',

link: 'https://www.alphapolis.co.jp/mypage/favorite',

},

];

const excludeList = [

['kakuyomu.jp/my/works/', 'new'],

['kakuyomu.jp/my/works/', 'edit'],

['kakuyomu.jp/my/works/', 'episodes'],

['syosetu.com/user', 'input'],

['www.alphapolis.co.jp/mypage/novel/save'],

['twitter.com'],

];

function eKeyHandler(e) {

switch (e.target.tagName.toLowerCase()) {

case 'input':

case 'textarea':

case 'select':

// disable while input

return;

}

let url = location.href;

for (let i=excludeList.length-1; i>=0; i--) {

let l = excludeList[i];

let r = true;

for (let j=l.length-1; j>=0; j--) {

if (!url.includes(l[j])) { r = false; break; }

}

if (r) return;

}

for (let i=list.length-1; i>=0; i--) {

let l = list[i];

if (url.includes(l.url)

&& l.code == e.code

&& l.modifiers.includes('+') == e.shiftKey

&& l.modifiers.includes('^') == e.ctrlKey

&& l.modifiers.includes('!') == e.altKey

&& l.modifiers.includes('#') == e.metaKey) {

switch (l.type) {

case 'a': // search <a> with content matched in innerHTML

{

let els = document.getElementsByTagName('a');

for (let j=els.length-1; j>=0; j--) {

if (els[j].innerHTML.includes(l.link)) {

location.href = els[j].href;

return;

}

}

}

break;

case 'aid': // search <a> by ID

{

let els = document.getElementsByTagName('a');

for (let j=els.length-1; j>=0; j--) {

if (els[j].id == l.link) {

location.href = els[j].href;

return;

}

}

}

break;

case 'atitle': // search <a> by title

{

let els = document.getElementsByTagName('a');

for (let j=els.length-1; j>=0; j--) {

if (els[j].title.includes(l.link)) {

location.href = els[j].href;

return;

}

}

}

break;

case 'aclass': // search <a> with class

{

let els = document.getElementsByTagName('a');

for (let j=els.length-1; j>=0; j--) {

if (els[j].classList.contains(l.link)) {

location.href = els[j].href;

return;

}

}

}

break;

case 'aclasstitle': // search <a> with class and title

{

let els = document.getElementsByTagName('a');

for (let j=els.length-1; j>=0; j--) {

if (els[j].classList.contains(l.links[0]) && els[j].title.includes(l.links[1])) {

location.href = els[j].href;

return;

}

}

}

break;

case 'adivclass': // search <div> with class within which <a>

{

let el = document.querySelector('.' + l.link + ' a');

location.href = el.href;

return;

}

break;

case 'aclick': // search <a> with content matched in innerHTML and click

{

let els = document.getElementsByTagName('a');

for (let j=els.length-1; j>=0; j--) {

if (els[j].innerHTML.includes(l.link)) {

els[j].click();

return;

}

}

}

break;

case 'spanclassesclick': // search <span> with classes and click

{

let els = document.getElementsByTagName('span');

for (let j=els.length-1; j>=0; j--) {

let k=l.links.length-1;

for (; k>=0 && els[j].classList.contains(l.links[k]); k--);

if (k < 0) {

els[j].click();

return;

}

}

}

break;

case 'inputnameclick': // search <input> by name and click

{

let els = document.getElementsByTagName('input');

for (let j=els.length-1; j>=0; j--) {

if (els[j].name.includes(l.link)) {

els[j].click();

return;

}

}

}

break;

case 'link': // search <link> by rel attr

{

let els = document.getElementsByTagName('link');

for (let j=els.length-1; j>=0; j--) {

if (els[j].rel == l.link) {

location.href = els[j].href;

return;

}

}

}

break;

case 'url': // jump to url

location.href = l.link;

return;

case 'inc': // increase number

location.href = url.replace(new RegExp(l.re), (match, p1) => l.str.replace('$$', Number(p1) + 1));

return;

case 'dec': // decrease number

location.href = url.replace(new RegExp(l.re), (match, p1) => l.str.replace('$$', Number(p1) - 1));

return;

}

}

}

}

document.addEventListener("keydown", eKeyHandler, false);

})();

///////////////////////////////////////////////////ここまで


操作方法

・カーソルキー左、またはテンキーのマイナス⇒前のエピソードを表示

・カーソルキー右、またはテンキーのプラス⇒次のエピソードを表示

・表紙でEnterキー、またはテンキーのEnterキー⇒現在読んでいるページを表示

・@キー、またはテンキーの3⇒ダッシュボードを表示

・[キー、またはテンキーの2⇒マイページを表示


カクヨム、なろう(感想欄含む)、アルファポリスに対応しています。

JavaScript がわかる人はキーをカスタマイズするなどして自分の使いやすいように改造してください。


ご質問があればお気軽にどうぞ。

  • Xで共有
  • Facebookで共有
  • はてなブックマークでブックマーク

作者を応援しよう!

ハートをクリックで、簡単に応援の気持ちを伝えられます。(ログインが必要です)

応援したユーザー

応援すると応援コメントも書けます

PCのブラウザでカクヨム小説を読む人向けのキーボードでページめくりできるスクリプト @PXXN3

★で称える

この小説が面白かったら★をつけてください。おすすめレビューも書けます。

カクヨムを、もっと楽しもう

この小説のおすすめレビューを見る

この小説のタグ