Skip to content

Instantly share code, notes, and snippets.

@motsu0
Created January 1, 2022 12:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save motsu0/3b5fc9b9a5d05f75f381543e459d12f6 to your computer and use it in GitHub Desktop.
Save motsu0/3b5fc9b9a5d05f75f381543e459d12f6 to your computer and use it in GitHub Desktop.
.board{
margin: 0 auto;
border-collapse: collapse;
}
.board-td{
box-sizing: border-box;
width: 50px;
height: 50px;
padding: 1px;
border: 1px solid #000;
}
.piece{
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
}
#piece1{
background-color: #FFCDD2;
color: #F44336;
}
#piece2{
background-color: #C8E6C9;
color: #4CAF50;
}
#piece3{
background-color: #BBDEFB;
color: #2196F3;
}
.hide{
display: none;
}
@media screen and (min-width:769px) {
.board-td{
width: 100px;
height: 100px;
}
.piece{
font-size: 48px;
}
}
<table class="board">
<tr>
<td class="board-td"></td>
<td class="board-td"></td>
<td class="board-td"></td>
<td class="board-td"></td>
<td class="board-td"></td>
</tr>
<tr>
<td class="board-td"></td>
<td class="board-td"></td>
<td class="board-td"></td>
<td class="board-td"></td>
<td class="board-td"></td>
</tr>
<tr>
<td class="board-td"></td>
<td class="board-td"></td>
<td class="board-td"></td>
<td class="board-td"></td>
<td class="board-td"></td>
</tr>
<tr>
<td class="board-td"></td>
<td class="board-td"></td>
<td class="board-td"></td>
<td class="board-td"></td>
<td class="board-td"></td>
</tr>
<tr>
<td class="board-td"><div id="piece1" class="piece" draggable="true">1</div></td>
<td class="board-td"></td>
<td class="board-td"><div id="piece2" class="piece" draggable="true">2</div></td>
<td class="board-td"></td>
<td class="board-td"><div id="piece3" class="piece" draggable="true">3</div></td>
</tr>
</table>
const board_td = document.getElementsByClassName('board-td');
const pieces = document.getElementsByClassName('piece');
//ドラッグ可能な要素(piece1~3)にリスナを追加する。
[...pieces].forEach(el=>{
//ドラッグ開始時に発火する関数dragStartを登録。
el.addEventListener('dragstart',dragStart);
//ドラッグ終了時に発火する関数dragEndを登録。
el.addEventListener('dragend',dragEnd);
});
//ドロップ可能な要素(ドロップされる要素)にリスナを追加する。
[...board_td].forEach((el,i)=>{
//ドラッグしながら重なった時にに発火する関数dragOverを登録。
el.addEventListener('dragover',dragOver);
//ドロップした時に発火する関数dropを登録。
//ドロップを受け入れた要素の情報が必要なため、elを引数として関数へ送っている。
el.addEventListener('drop',e=>{
drop(e,el);
});
});
function dragStart(e){
for(let i=0;i<board_td.length;i++){
//ドラッグ開始時点の親要素のindexと、ドラッグ中の要素のidを保存。
if(board_td[i]==e.target.parentElement){
e.dataTransfer.setData('text',JSON.stringify([e.target.id, String(i)]));
break;
}
}
//ドラッグ元の要素を隠す。
setTimeout(()=>{
e.target.classList.add('hide');
},1);
}
function dragOver(e){
//ドロップの禁止を解除する。
e.preventDefault();
}
function drop(e,el){
//ドラッグ開始時に保存した情報を取り出す。
//from[0]...ドラッグされている要素のid
//from[1]...ドラッグが開始された時点の親要素のindex
const from = JSON.parse(e.dataTransfer.getData('text'));
//ドロップ先に含まれるpiece
const content = el.getElementsByClassName('piece');
//ドロップ先に既にpieceが存在する場合
if(content.length==1){
//ドロップ開始時の親要素に、ドロップ先にあったpieceを移動。
board_td[Number(from[1])].appendChild(content[0]);
}
//ドロップ先に、ドラッグしていた要素を移動。
el.appendChild(document.getElementById(from[0]));
}
function dragEnd(e){
//隠していたpieceを表示
e.target.classList.remove('hide');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment