您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
DLsiteの検索結果ページで、左カラムの検索フォームをページ上部へ移動し、スクロール中も固定表示します。動的なページ更新にも対応します。
// ==UserScript== // @name DLsite Search Form at Top // @namespace https://x.com/kawaiiinf // @version 1.5.0 // @description DLsiteの検索結果ページで、左カラムの検索フォームをページ上部へ移動し、スクロール中も固定表示します。動的なページ更新にも対応します。 // @author Kawaii monkey // @license BSD 2-Clause // @match https://www.dlsite.com/* // @grant GM_addStyle // @run-at document-idle // ==/UserScript== (function () { 'use strict'; const MOVED_ATTR = 'data-dlst-moved'; const CONTAINER_ID = 'dlst-search-top-container'; const DEBUG = false; function log(...a){ if(DEBUG) console.log('[DLsite Search Top v1.4.3]', ...a); } function addStyle(css){ if (typeof GM_addStyle === 'function') GM_addStyle(css); else { const s=document.createElement('style'); s.textContent=css; document.head.appendChild(s); } } // 親へ sticky を適用 + タグ色分け用CSS addStyle(` *:has(> #${CONTAINER_ID}) { position: sticky; top: 0; z-index: 10; background: rgba(250, 250, 250, 0.85); backdrop-filter: saturate(1.05) blur(3px); border: #607194 1px solid; padding: 0.10rem 0.25rem; } #${CONTAINER_ID} { padding: 8px 10px; } #${CONTAINER_ID} input[type="search"] { width: calc(100% - 30px) !important; } /* タグ色分け(特異性を既存セレクタ以上にする) */ .search_tag_items li a.tag-game { background-color: #f5eaff; } .search_tag_items li a.tag-manga { background-color: #e6f7d6; } .search_tag_items li a.tag-cgillust { background-color: #e9f5ff; } `); // --- タグにクラスを付与 --- function colorizeTags() { document.querySelectorAll("ul.search_tag_items > li > a").forEach(a => { const text = a.textContent.trim(); a.classList.remove("tag-game","tag-manga","tag-cgillust"); if (text === "ゲーム") { a.classList.add("tag-game"); } else if (text === "マンガ") { a.classList.add("tag-manga"); } else if (text === "CG・イラスト") { a.classList.add("tag-cgillust"); } }); } function getTargets(){ const cpSearch = document.querySelector('.cp_search'); const searchTop = document.querySelector('.search_top'); if (!cpSearch || !searchTop) return null; const form = cpSearch.closest('form'); const parent = searchTop.parentElement || searchTop; if (!form || !parent) return null; return { cpSearch, form, searchTop, parent }; } function ensureContainer(searchTop){ let c = document.getElementById(CONTAINER_ID); if (!c){ c = document.createElement('div'); c.id = CONTAINER_ID; searchTop.after(c); log('Inserted container after .search_top'); } return c; } function moveFormIntoContainer(){ const t = getTargets(); if (!t) return; const { form, searchTop } = t; const container = ensureContainer(searchTop); if (form.getAttribute(MOVED_ATTR) === '1' && form.parentElement === container) return; container.appendChild(form); form.setAttribute(MOVED_ATTR, '1'); log('Form moved into container'); } function bootstrap(){ moveFormIntoContainer(); colorizeTags(); // SPA対応 let timer = 0; const obs = new MutationObserver(() => { clearTimeout(timer); timer = setTimeout(() => { moveFormIntoContainer(); colorizeTags(); }, 60); }); obs.observe(document.documentElement, { childList: true, subtree: true }); window.addEventListener('pageshow', () => { moveFormIntoContainer(); colorizeTags(); }, { once: true }); window.addEventListener('popstate', () => setTimeout(() => { moveFormIntoContainer(); colorizeTags(); }, 50)); document.addEventListener('turbo:load', () => { moveFormIntoContainer(); colorizeTags(); }); } if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', bootstrap); else bootstrap(); })();