Created
October 1, 2026 04:50
-
-
Save Cside/7fc71ac9b30c8a96c0f66765fd6b4340 to your computer and use it in GitHub Desktop.
はてなパークスの人気投稿を目立たせる
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // ==UserScript== | |
| // @name はてなパークスの人気投稿を目立たせる | |
| // @namespace http://tampermonkey.net/ | |
| // @version 2026-08-21 | |
| // @description はてなパークスの人気投稿を目立たせる | |
| // @author You | |
| // @match https://p.hatena.ne.jp/* | |
| // @icon https://www.google.com/s2/favicons?sz=64&domain=hatena.ne.jp | |
| // @grant none | |
| // ==/UserScript== | |
| (function() { | |
| 'use strict'; | |
| // ========================================== | |
| // 設定(色やフォントサイズをここで変更できます) | |
| // ========================================== | |
| // いいね数が5以上のコメントのスタイル | |
| const HIGHLIGHT_5_COLOR = '#000000'; | |
| const HIGHLIGHT_5_FONT_SIZE = '1.1em'; | |
| // いいね数が10以上のコメントのスタイル | |
| const HIGHLIGHT_10_COLOR = '#ff0000'; | |
| const HIGHLIGHT_10_FONT_SIZE = '1.1em'; | |
| // ========================================== | |
| // 1. スタイルをページに注入 | |
| // 設定した定数を用いてCSSを生成します | |
| const style = document.createElement('style'); | |
| style.textContent = ` | |
| .upvote-highlight-5, | |
| .upvote-highlight-5 p { | |
| font-size: ${HIGHLIGHT_5_FONT_SIZE} !important; | |
| font-weight: bold !important; | |
| color: ${HIGHLIGHT_5_COLOR} !important; | |
| } | |
| .upvote-highlight-10, | |
| .upvote-highlight-10 p { | |
| font-size: ${HIGHLIGHT_10_FONT_SIZE} !important; | |
| font-weight: bold !important; | |
| color: ${HIGHLIGHT_10_COLOR} !important; | |
| } | |
| `; | |
| document.head.appendChild(style); | |
| // 2. 投稿要素をチェックしてスタイル用のクラスを付け外しする関数 | |
| function processComment(commentEl) { | |
| // HTML標準のメタデータから確実なupvote数を取得 | |
| const countMeta = commentEl.querySelector('meta[itemprop="userInteractionCount"]'); | |
| if (!countMeta) return; | |
| const upvotes = parseInt(countMeta.getAttribute('content'), 10); | |
| // 既に同じupvote数で処理済みならスキップ (負荷軽減) | |
| if (commentEl.dataset.processedUpvotes === String(upvotes)) { | |
| return; | |
| } | |
| // --- 修正ポイント --- | |
| // 自身のコメントテキスト要素を特定する(ネストした子コメントのテキストを排除) | |
| const textEls = commentEl.querySelectorAll('[itemprop="text"]'); | |
| let myTextEl = null; | |
| for (const el of textEls) { | |
| // 一番近い親の li[itemprop="comment"] が自分自身であるかチェック | |
| if (el.closest('li[itemprop="comment"]') === commentEl) { | |
| myTextEl = el; | |
| break; // 自身のテキスト要素を見つけたらループを抜ける | |
| } | |
| } | |
| if (!myTextEl) return; | |
| // 一旦クラスをリセット(upvoteが減った場合なども考慮) | |
| myTextEl.classList.remove('upvote-highlight-5', 'upvote-highlight-10'); | |
| // upvote数に応じて対象のテキスト要素に直接クラスを付与 | |
| if (!isNaN(upvotes)) { | |
| if (upvotes >= 10) { | |
| myTextEl.classList.add('upvote-highlight-10'); | |
| } else if (upvotes >= 5) { | |
| myTextEl.classList.add('upvote-highlight-5'); | |
| } | |
| } | |
| // 現在の処理済みupvote数を記憶 | |
| commentEl.dataset.processedUpvotes = String(upvotes); | |
| } | |
| // 3. ページ内の全コメントを対象に処理を走らせる関数 | |
| function processAllComments() { | |
| const comments = document.querySelectorAll('li[itemprop="comment"]'); | |
| comments.forEach(processComment); | |
| } | |
| // 初回実行 | |
| processAllComments(); | |
| // 4. DOMの変更を監視 (非同期読み込み & リアルタイムなupvote増減に対応) | |
| const observer = new MutationObserver(() => { | |
| processAllComments(); | |
| }); | |
| observer.observe(document.body, { | |
| childList: true, // 要素の追加や削除を監視 | |
| subtree: true, // 子孫要素も対象にする | |
| attributes: true, | |
| attributeFilter: ['content'] // metaタグの数値(content属性)の変動も監視 | |
| }); | |
| })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment