Narou ranking ng

小説家になろう(厳密には小説を読もう)ランキングでのNGフィルタリング機能を提供

目前為 2020-02-21 提交的版本,檢視 最新版本

// ==UserScript==
// @name         Narou ranking ng
// @namespace    https://gf.qytechs.cn/ja/users/17828-amaicoffee
// @version      1.3
// @description  小説家になろう(厳密には小説を読もう)ランキングでのNGフィルタリング機能を提供
// @author       amaicoffee
// @license      MIT license
// @match        https://yomou.syosetu.com/rank/genrelist/type/*
// @match        https://yomou.syosetu.com/rank/list/type/*
// @grant        GM_getValue
// @grant        GM_setValue
// ==/UserScript==

/*
更新履歴
    ver 1.3
    メニュー作成を目指してとりあえずNGセーブデータのエクスポート機能を実装。
    NGセーブデータボタン横にエクスポートボタンを追加。
    なおこれは暫定的な配置です。良くない配置のUIなのでメニュー実装までのつなぎです。
    エクスポートボタンを押すとコンソールにNGセーブデータが表示されます。
    コンソールはF12を押すことで見られます。後は適宜保存するなどお願いします。

    ver 1.2
    load_ng_ids()を三項演算子ショートハンド。
    NGボタンにaddEventListenerする部分をNGボタン作成部分に合流させた。
*/

/*
ユーザースクリプトの説明
    注意!このスクリプトはJavaScript練習を兼ねたものです!
    小説を読もう!の「ジャンル別ランキング」「総合ランキング」ページで動作するスクリプトで、
    ランキング内、小説タイトル横に追加する「表示/非表示」ボタンを押すと、その小説はNGに登録され説明文が折りたたまれます。
    NG登録はGM setValueで保存され、ページ遷移に耐えます。
    登録したNGを消す方法は画面右下のフローティングボタン「delete ng data」を押して下さい。
*/


/*
残った問題点
    命名規則の統一
    関数(メソッド?)に分離できるところはする
    グローバル変数をなくす(全体を即時実行関数の中にしまってグローバル汚染をなくす)
*/
// スクリプトでNG小説を隠すのに使うCSS要素を作成して追加
var CENSORED_STYLE = document.createElement('style');
CENSORED_STYLE.innerHTML = ".censored { display: none; }";
document.head.appendChild(CENSORED_STYLE);


// ランキング内の小説をノードリストとして所得
var ranking_list_list = document.querySelectorAll('.ranking_list');


// セーブデータ保存・読込用キー
const NAROU_NG_IDS_KEY = 'narou_ng_ids';


function load_ng_ids() {
    const DATA = GM_getValue(NAROU_NG_IDS_KEY);
    return (DATA ? DATA.split(' ') : []); // セーブデータは空白区切り文字列。加工して配列に。
}


function save_ng_ids(array) {
    GM_setValue(NAROU_NG_IDS_KEY, array.join(' '));
}


// ランキング内小説ID配列とNG小説ID配列
// e => a.firstElementChild.getAttribute('href').substr(-8, 7) substrは削除予定
var ranked_id_arr = Array.from(document.querySelectorAll('.tl'), a => a.href.substring(26, 33));
var ng_id_arr = load_ng_ids();


// NG登録ボタンを↑のリスト個数分つくって配列に追加
var button_array = [];
for (let i = 0; i < ranking_list_list.length; i++) {
    button_array[i] = document.createElement('button');
    button_array[i].innerText = '表示 / 非表示';
    button_array[i].classList.add('ngbtn');// 苦肉の策
    button_array[i].addEventListener('click', function () { toggle(i); });// XXX:ループ内関数宣言は駄目らしい? 動いているが…
    ranking_list_list[i].firstElementChild.appendChild(button_array[i]);
}


function toggle(num) {
    var target_classList = ranking_list_list[num].lastElementChild.classList;
    var target_id = ranked_id_arr[num];
    if (target_classList.contains('censored')) {
        target_classList.remove('censored');
        ng_id_arr = ng_id_arr.filter(id => id != target_id);
    } else {
        target_classList.add('censored');
        ng_id_arr.push(target_id);
    }
    console.log('ng id array changed -->');
    console.log(ng_id_arr);
    save_ng_ids(ng_id_arr);
}


// メイン部分。ここどうにかならないものか
if (ng_id_arr.length > 0) {
    console.log('save data found');
    console.log(ng_id_arr);
    let key_array = ng_id_arr.slice();
    for (let i = 0; i < ranked_id_arr.length; i++) {
        for (let j = 0; j < key_array.length; j++) {

            let soeji = ranked_id_arr.indexOf(key_array[j]);
            if (soeji != -1) {
                ranking_list_list[soeji].lastElementChild.classList.add('censored');
                key_array.splice(j, 1);
            }
        }
    }
} else {
    console.log('save data not found');
}


// フロートNGメニュー
const NG_MENU_STYLE = document.createElement('style');
NG_MENU_STYLE.innerHTML = ".floated { position: fixed; right: 0; bottom: 0; }";
document.head.appendChild(NG_MENU_STYLE);


const FLOAT_NG_MENU = document.createElement('div');
FLOAT_NG_MENU.classList.add('floated');
document.body.appendChild(FLOAT_NG_MENU);


const EXPORT_BUTTON = document.createElement('button');
EXPORT_BUTTON.innerText = 'export ng data';
EXPORT_BUTTON.addEventListener('click', function () {
    console.log(ng_id_arr);
    window.alert('ng save data expoted to console')
});
document.querySelector('.floated').appendChild(EXPORT_BUTTON);




const DELETE_SAVE_DATA_BUTTON = document.createElement('button');
DELETE_SAVE_DATA_BUTTON.innerText = 'delete ng data';
DELETE_SAVE_DATA_BUTTON.addEventListener('click', delete_save_data);
document.querySelector('.floated').appendChild(DELETE_SAVE_DATA_BUTTON);


function delete_save_data() {
    const blank_data = '';
    GM_setValue(NAROU_NG_IDS_KEY, blank_data);
    window.alert('ng data has deleted');
}

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址