HTML5のdraggable属性とjavascriptを使用して自由にドラッグドロップできるようにしました。
下のコードを完コピしてもらえれば確認していただけると思いますが、
左側にドラッグ対象の要素(numberBox)が縦に20個並んでいるボックス(drop_back_box)があり、
右側には横長のボックス(dropBox)が縦に5個並んでいます。
numberBoxをdropBoxやdrop_back_boxにドラッグ・ドロップするのは簡単にできたのですが、
dropBoxに複数ドロップされたnumberBox間で左右にドラッグドロップできるようにするのに
かなり手こずってしまいました。
ドロップされたnumberBox間で左右にドラッグドロップするためにはnumberBox自体に
ondrop属性を持たせてjavascriptのinsertBeforeを使用することで簡単にできました。。。
こんな簡単なことをなぜすぐに気づかなかったのか。。。
HTML5のdraggable属性はドラッグした要素やドロップ先の要素の情報を取得できるのでかなり便利です。
コードは下記の通りです!
<style>
.left_box {
width: 110px;
height:700px;
background:#fff;
margin-right: 56px;
}
.drag_box {
width: 100px;
height: 30px;
background: red;
margin: 2px;
}
.right_box {
background: #fff;
height: 700px;
width: 110px;
}
.drop_box {
width:800px;
height:38px;
margin:2px;
background:yellow;
display: flex;
}
</style>
<!-- 左のボックス -->
<div style="display:flex;">
<div class="left_box">
<div class="drop_back_box" ondragover="dragover(event)" ondrop="dropBack(event)">
<?php for ($i=1; $i < 21; $i++): ?>
<div class="drag_box" id="numberBox<?php echo $i; ?>" draggable="true" ondragstart="f_dragstart(event)" ondrop="dropLR(event)">
ナンバー:<?php echo $i; ?>
</div>
<?php endfor; ?>
</div>
</div>
<!-- 右のボックス -->
<div class="right_box">
<?php $i=1; for($i=1; $i < 6; $i++): ?>
<div id="dropBox<?php echo $i; ?>" class="drop_box" ondragover="dragover(event)" ondrop="drop(event)">
</div>
<?php endfor; ?>
</div>
</div>
<script>
/***** ドラッグ開始時の処理 *****/
function f_dragstart(event){
//ドラッグするデータのid名をDataTransferオブジェクトにセット
event.dataTransfer.effectAllowed = 'move';
event.dataTransfer.setData("text", event.target.id);
}
/***** ドラッグ要素がドロップ要素に重なっている間の処理 *****/
function dragover(event){
event.dataTransfer.effectAllowed = 'move';
//dragoverイベントをキャンセルして、ドロップ先の要素がドロップを受け付けるようにする
event.preventDefault();
}
/***** 右のボックスにドロップ時の処理 *****/
function drop(event){
// ドラッグされたデータのid名をDataTransferオブジェクトから取得
const boxId = event.dataTransfer.getData("text");
const numberBox = document.getElementById(boxId);
const dropBox = event.currentTarget;
dropBox.appendChild(numberBox);
// エラー回避のため、ドロップ処理の最後にdropイベントをキャンセルしておく
event.preventDefault();
};
function dropLR(event){
// ドラッグされたデータのid名をDataTransferオブジェクトから取得
const draggedEleId = event.dataTransfer.getData("text");
// ドラッグされた要素を取得
const draggedElement = document.getElementById(draggedEleId);
// ドロップされた要素を取得
const dropedElement = event.currentTarget;
// ①ドロップ先の親要素のid名を取得
const dropedParentId = event.currentTarget.parentNode.id;
const dropBox = document.getElementById(dropedParentId);
// 左のボックスに戻す時以外は要素間の左右にドロップできる処理
dropBox.insertBefore(draggedElement, dropedElement)
// エラー回避のため、ドロップ処理の最後にdropイベントをキャンセルしておく
event.preventDefault();
event.stopPropagation();
};
// 左のボックスにドロップする処理
function dropBack(event){
// エラー回避のため、ドロップ処理の最後にdropイベントをキャンセルしておく
event.preventDefault();
}
</script>
まだまだ自分の応用力のなさを痛感してばかりですが、これからもプログラミング頑張ろうと思います!