Greasy Fork

Greasy Fork is available in English.

DLsite Search Form at Top

DLsite.com の検索結果画面の左側検索入力を検索結果のトップに複製し、追従するようにします。

当前为 2025-07-31 提交的版本,查看 最新版本

// ==UserScript==
// @name         DLsite Search Form at Top
// @namespace    https://x.com/kawaiiinf
// @version      1.1
// @description  DLsite.com の検索結果画面の左側検索入力を検索結果のトップに複製し、追従するようにします。
// @author       Kawaii monkey
// @license      BSD 2-Clause
// @match        https://www.dlsite.com/*
// ==/UserScript==

(function() {
    'use strict';

    /**
     * メインの処理を実行する関数。
     * .cp_search要素の祖先にあるformタグを検索し、その複製を.search_topの直後に挿入する。
     * 複製したform内の入力欄の幅を調整し、.search_topの親要素を追従させる。
     */
    function executeEnhancedSearchForm() {
        console.log('[DLsite.com 検索フォーム 複製] メイン処理を実行します。');

        // .cp_search要素と.search_top要素を直接取得
        const cpSearchElement = document.querySelector('.cp_search');
        const searchTopElement = document.querySelector('.search_top');

        // 必須要素が存在しない場合は処理を中断
        if (!cpSearchElement || !searchTopElement) {
            console.log('[DLsite.com 検索フォーム 複製] .cp_searchまたは.search_top要素が見つかりませんでした。');
            return; // ここで処理を終了
        }

        // .search_topの親要素を取得
        const searchTopParent = searchTopElement.parentElement;

        // 親要素が存在する場合、スタイルを適用して追従させる
        if (searchTopParent) {
            // position: 'sticky' は、要素がスクロールに応じて特定の位置に留まるようにする
            searchTopParent.style.position = 'sticky';
            // top: '0' は、画面の上端を基準に位置を固定する
            searchTopParent.style.top = '0';
            // z-index: '1' は、要素の重なり順を指定する。他の要素より手前に表示させるため
            searchTopParent.style.zIndex = '1';
			// background-color を指定して見やすくする
			searchTopParent.style.backgroundColor = 'rgb(241 241 241 / 70%)';
            console.log('[DLsite.com 検索フォーム 複製] .search_topの親要素にsticky設定を適用しました。');
        } else {
            console.log('[DLsite.com 検索フォーム 複製] .search_topの親要素が見つかりませんでした。');
        }

        // .cp_searchの最も近い祖先form要素を取得
        // closest('form')は、指定されたセレクターに一致する最も近い祖先要素(自身を含む)を返す
        const parentForm = cpSearchElement.closest('form');

        // formタグが見つからなかった場合は処理を中断
        if (!parentForm) {
            console.log('[DLsite.com 検索フォーム 複製] .cp_searchの祖先にformタグが見つかりませんでした。');
            return; // ここで処理を終了
        }

        // formタグを複製
        // cloneNode(true)は、要素とそのすべての子孫要素も深く複製する
        const clonedForm = parentForm.cloneNode(true);

        // 複製したformタグを.search_top要素の直後に挿入
        // searchTopElement.after(clonedForm)は、searchTopElementのすぐ後ろにclonedFormを挿入する
        searchTopElement.after(clonedForm);
        console.log('[DLsite.com 検索フォーム 複製] Formが複製され、.search_topの直後に挿入されました。');

        // 複製したformの中からtype="search"のinput要素(入力欄)を探す
        const inputElement = clonedForm.querySelector('input[type="search"]');

        // input要素が見つかった場合、幅を調整
        if (inputElement) {
            // 幅を計算し、スタイルに適用する。calc()関数で100%から30pxを引く
            inputElement.style.width = 'calc(100% - 30px)';
            console.log('[DLsite.com 検索フォーム 複製] 複製されたform内の入力欄の幅を調整しました。');
        } else {
            console.log('[DLsite.com 検索フォーム 複製] 複製されたform内に入力欄(input[type="search"])が見つかりませんでした。');
        }
    }

    // window.loadイベントリスナーを追加する
    // loadイベントは、ページ上の全てのコンテンツが完全に読み込まれた後に発火する
    window.addEventListener('load', function() {
        // loadイベント発火後、すぐにメイン処理(executeEnhancedSearchForm関数)を実行する
        executeEnhancedSearchForm();
    });
})();