以下の内容はhttps://hhelibex.hatenablog.jp/entry/2025/10/16/223805より取得しました。


異なるiframe間でドラッグ&ドロップでやり取りする

はじめに

ちょっとお仕事で必要が生じて、異なるiframe間でドラッグ&ドロップでデータをやり取りする機能を実装することになったので、その検証メモ。

今回は、Laravelを使って組んでいく。

なお、実行環境は以下だが、構築の詳細は割愛。

下準備

まずはLaravelのプロジェクトを作る。

cd /var/www/html
composer create-project laravel/laravel:11.* sample07
chmod -R a+w  sample07/storage/
chmod a+w  sample07/bootstrap/cache

お仕事がLaravel 11なので、バージョンとしてLaravel 11系を指定しているが、最新のLaravel 12系でも問題なく動くと思う。

ファイルの作成・編集

sample07/resources/views/sample/index.blade.php

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8" />
    <base href="/sample07/public/" />
    <title>親ページ</title>
    <link rel="stylesheet" type="text/css" href="sample.css" />
    <script type="text/javascript" src="sample.js"></script>
</head>

<body>
    <h1>親ページ</h1>

    <iframe width="100%" height="300" src="sample/frame1"></iframe>
    <iframe width="100%" height="300" src="sample/frame2"></iframe>
</body>

</html>

sample07/resources/views/sample/frame1.blade.php

ドラッグ元。

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8" />
    <base href="/sample07/public/" />
    <title>ドラッグ元</title>
    <link rel="stylesheet" type="text/css" href="sample.css" />
    <script type="text/javascript" src="sample.js"></script>
</head>

<body>
    <h1>ドラッグ元</h1>

    <table>
        <thead>
            <tr>
                <th>商品番号</th>
                <th>商品名</th>
            </tr>
        </thead>
        <tbody>
            <tr data-id="A12345" class="draggable" draggable="true">
                <td>A12345</td>
                <td>こしひかり</td>
            </tr>
            <tr data-id="B67890" class="draggable" draggable="true">
                <td>B67890</td>
                <td>あきたこまち</td>
            </tr>
            <tr data-id="C54321" class="draggable" draggable="true">
                <td>C54321</td>
                <td>ゆめぴりか</td>
            </tr>
        </tbody>
    </table>
    <script type="text/javascript">
        initDrag();
    </script>
</body>

</html>

sample07/resources/views/sample/frame2.blade.php

ドロップ先。

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8" />
    <base href="/sample07/public/" />
    <title>ドロップ先</title>
    <link rel="stylesheet" type="text/css" href="sample.css" />
    <script type="text/javascript" src="sample.js"></script>
</head>

<body>
    <h1>ドロップ先</h1>

    <div id="dropzone" class="dropzone">ドロップターゲット</div>

    <script type="text/javascript">
        initDrop();
    </script>
</body>

</html>

sample07/app/Http/Controllers/SampleController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class SampleController extends Controller
{
    public function index()
    {
        return view('sample.index');
    }
    public function frame1()
    {
        return view('sample.frame1');
    }
    public function frame2()
    {
        return view('sample.frame2');
    }
}

sample07/public/sample.css

table {
    border-collapse: collapse;
    outline: none;
}
th,
td {
    border: 1px solid #ccc;
}

.draggable {
    cursor: grab;
}
.dropzone {
    min-height: 150px;
    border: 2px dashed #999;
    background-color: #e9e9e9;
    padding: 10px;
}
.dropzone.drag-over {
    background-color: #d1ffd1;
    border-color: green;
}

sample07/public/sample.js

function initDrag() {
    const draggables = document.querySelectorAll(".draggable");
    draggables.forEach((draggable) => {
        draggable.addEventListener("dragstart", (ev) => {
            console.log(draggable.dataset.id + ": Drag start");

            // ドラッグするデータの種類と値を設定
            ev.dataTransfer.setData(
                "text/dataIds",
                JSON.stringify([draggable.dataset.id])
            );

            // ドラッグ元の要素を一時的に非表示にする
            setTimeout(() => {
                draggable.style.opacity = "0.5";
            }, 0);
        });
        draggable.addEventListener("dragend", (ev) => {
            // ドラッグ終了時に元のスタイルに戻す
            draggable.style.opacity = "1";
        });
    });
}
function initDrop() {
    const dropZone = document.querySelector("#dropzone");
    dropZone.addEventListener("dragover", (ev) => {
        ev.preventDefault();
        dropZone.classList.add("drag-over");
    });

    dropZone.addEventListener("dragleave", (ev) => {
        dropZone.classList.remove("drag-over");
    });

    dropZone.addEventListener("drop", (ev) => {
        ev.preventDefault();

        const data = ev.dataTransfer.getData("text/dataIds");
        const dataIds = JSON.parse(data);

        // ドロップ時のアクション
        console.log(dataIds);

        dropZone.classList.remove("drag-over");
    });
}

今回は検証なので、ドロップ時の処理はコンソールにドラッグされた要素のIDを出力するだけ。

sample07/routes/web.php

<?php

use Illuminate\Support\Facades\Route;

Route::get('/', function () {
    return view('welcome');
});

Route::get('/sample', [\App\Http\Controllers\SampleController::class, 'index']);
Route::get('/sample/frame1', [\App\Http\Controllers\SampleController::class, 'frame1']);
Route::get('/sample/frame2', [\App\Http\Controllers\SampleController::class, 'frame2']);

動作確認

以下のURLにアクセスして動作確認。

http://<your-ip-address>/sample07/public/sample

ドラッグ元のテーブルの行をドラッグして、ドロップ先にドロップしたときにIDがコンソールに出力されれば完成。

参考

Geminiと会話しながら作りました。

share.google

share.google




以上の内容はhttps://hhelibex.hatenablog.jp/entry/2025/10/16/223805より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14