🙆

マウスでドラッグすることができるライブラリを作成しました

に公開

index.htmlで保存。

function enableDragToScroll(targetElement) {

が今回作成したライブラリです。

(AI が製作)

プロンプト


マウスで、左クリックホールドすると、マウスをクリックした段階の座標を保持しておき、その変化量分をスクロールする処理を、実行してほしい

想定している使用用途

文書量の多いサイトでの使用

マウスのスクロールだと、調整が難しいかつ、どこに文書が移動したかがわかりづらい。

このコードを使うと、シームレスな読書体験?が可能です。

試す

https://kemii.sakura.ne.jp/all/mouse_scroll_sample/index.html

以下をコピーすることで試すことができます。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>単一ページドラッグスクロールウェブサイト</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <style>
        /* Interフォントを適用 */
        body {
            font-family: "Inter", sans-serif;
            margin: 0;
            /* デフォルトのスクロールを許可 */
            overflow-x: hidden; /* 横方向のスクロールバーは隠す */
            user-select: none; /* テキスト選択を無効にする */
            -webkit-user-select: none; /* Safari */
            -moz-user-select: none; /* Firefox */
            -ms-user-select: none; /* IE/Edge */
            min-height: 200vh; /* 縦スクロールを発生させるための十分な高さ */
            background-color: #f3f4f6; /* gray-100 */
            line-height: 1.6;
            color: #374151; /* gray-700 */
        }

        /* ヘッダーとフッターの基本スタイル */
        .header, .footer {
            padding: 2rem;
            text-align: center;
            background-color: #1f2937; /* gray-800 */
            color: white;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        .header {
            border-bottom-left-radius: 0.75rem;
            border-bottom-right-radius: 0.75rem;
        }
        .footer {
            border-top-left-radius: 0.75rem;
            border-top-right-radius: 0.75rem;
        }

        .main-content {
            padding: 2rem;
            max-width: 800px; /* コンテンツの幅を制限 */
            margin: 0 auto;
            background-color: white;
            border-radius: 0.75rem;
            box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
            margin-top: 2rem;
            margin-bottom: 2rem;
        }

        .section-title {
            font-size: 2rem;
            font-weight: 600;
            color: #1f2937; /* gray-800 */
            margin-bottom: 1rem;
            border-bottom: 2px solid #e5e7eb; /* gray-200 */
            padding-bottom: 0.5rem;
        }

        .content-block {
            margin-bottom: 1.5rem;
            padding: 1rem;
            background-color: #f9fafb; /* gray-50 */
            border-radius: 0.5rem;
            border: 1px solid #e5e7eb; /* gray-200 */
        }

        .content-block p {
            margin-bottom: 0.5rem;
        }

        /* スクロールを促すためのダミーコンテンツ */
        .dummy-content {
            height: 80vh; /* 縦スクロールを確保するための高さ */
            background-color: #d1d5db; /* gray-300 */
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 2rem;
            color: #4b5563; /* gray-600 */
            border-radius: 0.75rem;
            margin-bottom: 2rem;
            text-align: center;
        }
    </style>
</head>
<body>

    <header class="header">
        <h1 class="text-4xl font-bold mb-2">単一ページドラッグスクロールウェブサイト</h1>
        <p class="text-lg">このページは、マウスドラッグで縦にスクロールできます。</p>
    </header>

    <main class="main-content">
        <section class="mb-8">
            <h2 class="section-title">ようこそ!</h2>
            <div class="content-block">
                <p>
                    このウェブサイトは、通常の縦スクロールに対応しています。
                    さらに、マウスの左クリックまたは右クリックをホールドしてドラッグすることで、
                    ページ全体を上下にスクロールできる機能を実装しました。
                </p>
                <p>
                    スマートフォンでのスワイプ操作のように、直感的にコンテンツを閲覧できます。
                    ぜひ、マウスでドラッグしてスクロールしてみてください。
                </p>
            </div>
        </section>

        <section class="mb-8">
            <h2 class="section-title">コンテンツセクション 1</h2>
            <div class="content-block">
                <p>
                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
                </p>
                <p>
                    Nulla facilisi. Integer ac leo at nunc bibendum fermentum. Proin eget dolor sit amet velit fermentum.
                </p>
            </div>
        </section>

        <section class="mb-8">
            <h2 class="section-title">スクロールを試してください!</h2>
            <div class="dummy-content">
                マウスをドラッグしてスクロール!
            </div>
        </section>

        <section class="mb-8">
            <h2 class="section-title">コンテンツセクション 2</h2>
            <div class="content-block">
                <p>
                    Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Maecenas sed diam eget risus varius blandit sit amet non magna.
                </p>
                <p>
                    Donec id elit non mi porta gravida at eget metus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.
                </p>
            </div>
        </section>

        <section class="mb-8">
            <h2 class="section-title">さらに下のコンテンツ</h2>
            <div class="content-block">
                <p>
                    Pellentesque ornare sem lacinia quam venenatis vestibulum. Nullam id dolor id nibh ultricies vehicula ut id elit.
                </p>
                <p>
                    Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id ligula porta felis euismod semper.
                </p>
            </div>
        </section>
    </main>

    <footer class="footer">
        <p>&copy; 2025 単一ページドラッグスクロールデモ</p>
    </footer>

    <script>
        /**
         * マウスドラッグで要素をスクロールさせる機能を提供するライブラリ。
         * 主に縦方向のスクロールを想定しているが、横方向にも対応可能。
         *
         * @param {HTMLElement | Window} targetElement - スクロールを制御する対象のDOM要素、またはWindowオブジェクト。
         */
        function enableDragToScroll(targetElement) {
            let isDragging = false;
            let startX = 0;
            let startY = 0;
            let initialScrollLeft = 0; // 横スクロール用
            let initialScrollTop = 0;  // 縦スクロール用

            // スクロール対象の要素がWindowオブジェクトかHTMLElementかを判断
            const isWindow = targetElement === window;
            const scrollElement = isWindow ? document.documentElement : targetElement;

            /**
             * マウスダウンイベントハンドラ。
             * ドラッグの開始点を記録し、ドラッグ状態を有効にする。
             * @param {MouseEvent} e - マウスイベントオブジェクト。
             */
            const handleMouseDown = (e) => {
                // 左クリック (button === 0) または右クリック (button === 2) でドラッグを開始
                // 右クリックの場合、コンテキストメニューの表示を抑制
                if (e.button === 2) {
                    e.preventDefault();
                }

                if (e.button === 0 || e.button === 2) {
                    isDragging = true;
                    startX = e.clientX;
                    startY = e.clientY;
                    initialScrollLeft = scrollElement.scrollLeft;
                    initialScrollTop = scrollElement.scrollTop;

                    // テキスト選択などのブラウザのデフォルト動作を防ぐ
                    e.preventDefault();
                }
            };

            /**
             * マウス移動イベントハンドラ。
             * ドラッグ中に要素のスクロール位置を更新する。
             * @param {MouseEvent} e - マウスイベントオブジェクト。
             */
            const handleMouseMove = (e) => {
                if (!isDragging) return;

                const currentX = e.clientX;
                const currentY = e.clientY;

                const deltaX = currentX - startX;
                const deltaY = currentY - startY;

                // スクロール位置を更新
                // 横スクロールが必要な場合は、scrollLeftも更新
                // scrollElement.scrollLeft = initialScrollLeft - deltaX;
                scrollElement.scrollTop = initialScrollTop - deltaY;
            };

            /**
             * マウスアップイベントハンドラ。
             * ドラッグ状態を無効にする。
             * @param {MouseEvent} e - マウスイベントオブジェクト。
             */
            const handleMouseUp = () => {
                isDragging = false;
            };

            /**
             * コンテキストメニューイベントハンドラ。
             * 右クリックメニューの表示を抑制する。
             * @param {MouseEvent} e - マウスイベントオブジェクト。
             */
            const handleContextMenu = (e) => {
                e.preventDefault();
            };

            // イベントリスナーを登録
            targetElement.addEventListener('mousedown', handleMouseDown);
            // mousemoveとmouseupはdocument全体でリッスンし、ドラッグ中にカーソルが要素から外れても対応できるようにする
            document.addEventListener('mousemove', handleMouseMove);
            document.addEventListener('mouseup', handleMouseUp);
            targetElement.addEventListener('contextmenu', handleContextMenu);

            // クリーンアップ関数 (必要に応じて)
            return () => {
                targetElement.removeEventListener('mousedown', handleMouseDown);
                document.removeEventListener('mousemove', handleMouseMove);
                document.removeEventListener('mouseup', handleMouseUp);
                targetElement.removeEventListener('contextmenu', handleContextMenu);
            };
        }

        document.addEventListener('DOMContentLoaded', () => {
            // body要素またはdocument.documentElementにドラッグスクロールを適用
            // document.documentElement はドキュメントのルート要素 (<html>) を指し、
            // ページのスクロールを制御するのに適しています。
            enableDragToScroll(document.documentElement);
        });
    </script>
</body>
</html>


Discussion