Skip to content

Instantly share code, notes, and snippets.

@Cside
Created October 1, 2026 04:50
Show Gist options
  • Select an option

  • Save Cside/7fc71ac9b30c8a96c0f66765fd6b4340 to your computer and use it in GitHub Desktop.

Select an option

Save Cside/7fc71ac9b30c8a96c0f66765fd6b4340 to your computer and use it in GitHub Desktop.
はてなパークスの人気投稿を目立たせる
// ==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