質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

2回答

877閲覧

JavaScriptでdivの中のお魚.pngをドラッグで自由に動かしたいです

saurinn

総合スコア11

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

2クリップ

投稿2023/01/25 01:19

編集2023/01/25 05:35

マウスでお魚を動かしたいのですが。。。

ドラッグアンドドロップでお魚を別のdivコンテナへ
移動先のdivコンテナの中でドラッグしてお魚を移動させるという練習プログラムを書いています。

実現したいこと

お魚のpngが3つあるのですが、クリックしたお魚をドラッグアンドドロップできるようにしたいのですがうまい方法が見つかりません。

発生している問題・エラーメッセージ

変数sakanaの中にimg要素のdragid,dragid2,dragid3を入れていきたいのですが、うまく切り替える方法はないでしょうか。

javascript

1let target = ""; 2const dragid = document.getElementById('dragid'); 3const daragid2 = document.getElementById('dragid2'); 4const daragid3 = document.getElementById('dragid3'); 5 6const dropbox = document.getElementById('dropbox'); 7 8let sakana = dragid; 9 10/*dragid,dragid2,dragid3をクリックすると変数sakanaに入るようにしたい */ 11//上のdivから下のdivへドラッグアンドドロップ 12window.onload = function () { 13 sakana.addEventListener('dragstart', function (element) { 14 target = element.target; 15 }, false); 16 17 dropbox.addEventListener('dragover', function (element) { 18 element.preventDefault(); 19 }, false); 20 21 dropbox.addEventListener('drop', function (element) { 22 element.preventDefault(); 23 element.target.appendChild(target); 24 drag_fish(); 25 }, false); 26} 27 28//dropboxの中でドラッグ移動 29function drag_fish(){ 30 draggable(sakana); 31 32 function draggable(target) { 33 target.onmousedown = function () { 34 document.onmousemove = mouseMove; 35 }; 36 document.onmouseup = function () { 37 document.onmousemove = null; 38 }; 39 40 function mouseMove(e) { 41 var event = e ? e : window.event; 42 // 要素の位置座標を取得 43 var clientRect = dropbox.getBoundingClientRect(); 44 45 // ページの左端から、要素の左端までの距離 46 var px = window.pageXOffset + clientRect.left; 47 48 // ページの上端から、要素の上端までの距離、数字はdivのサイズから画像サイズを引いたもの 49 var py = window.pageYOffset + clientRect.top; 50 target.style.position = 'absolute' 51 if (event.clientY > py && event.clientY < py + 234) { 52 target.style.top = event.clientY + 'px'; 53 } 54 if (event.clientX > px && event.clientX < px + 540) { 55 target.style.left = event.clientX + 'px'; 56 } 57 } 58 } 59}

こちらはHTMLとCSSです

dataインデックスなども使えないかといろいろ試してimgの要素がカオスになっていてすみません💦

HTML

1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <link rel="stylesheet" href="./aqua.css"> 8 <title>水族館</title> 9</head> 10<body> 11 <div class="container"> 12 <h1>お空にお魚を泳がせよう!</h1> 13 <div class="dragcontainer"> 14 <img id="dragid" data-id="dragid" src="img/kame-l.png" width="160px"> 15 <img id="dragid2" data-id="dragid2" src="img/fish01.PNG" width="160px" height="138px"> 16 <img id="dragid3" data-id="dragid3" src="img/fuku.PNG" width="160px" height="138px"> 17 </div> 18 <div class="dropcontainer" id="dropbox"></div> 19 </div> 20 <script src="js/aqua.js"></script> 21</body> 22</html>

こちらがCSSです。よろしくお願いします。

CSS

1/* CSSのリセット */ 2html, 3body, 4ul, 5ol, 6li, 7h1, 8h2, 9h3, 10h4, 11h5, 12h6, 13p, 14form, 15input, 16div { 17 margin: 0; 18 padding: 0; 19} 20body { 21 font-family: "Avenir Next", "Hiragino Kaku Gothic ProN W3", sans-serif; 22} 23button { 24 -webkit-appearance: none; 25 appearance: none; 26 vertical-align: middle; 27 border: 0; 28 background: transparent; 29 padding: 0; 30 margin: 0; 31 outline: 0; 32 border-radius: 0; 33} 34li { 35 list-style: none; 36} 37/*コンテンツ*/ 38.container{ 39 background-color: aquamarine; 40 text-align: center; 41 height: 100vh; 42} 43.dragcontainer{ 44 width: 700px; 45 height: 200px; 46 border: 2px solid black; 47 margin: 10px auto; 48 background-color: white; 49} 50.dropcontainer{ 51 background-image: url("img/sky02.jpg"); 52 width: 700px; 53 height: 394px; 54 border: 2px solid black; 55 margin: 10px auto; 56} 57

試したこと

onclickで変数の要素を切り替えようと思ったのですが、うまくいきませんでした。
dragstartと機能がダブってしまうからでしょうか?

let sakana = dragid; dragid.onclick=function(){ sakana = dragid; } dragid2.onclick=function(){ sakana = daragid2; } dragid3.onclick=function(){ sakana = daragid3; }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ざっくりこんな感じでどうでしょう?

javascript

1<script> 2window.addEventListener('DOMContentLoaded', ()=>{ 3 const drag={}; 4 document.addEventListener('mousedown',e=>{ 5 const t=e.target; 6 console.log(t); 7 if(t.matches('.draggable')){ 8 drag.offsetX= t.closest('svg').getBoundingClientRect().left +e.clientX -t.getBoundingClientRect().left; 9 drag.offsetY= t.closest('svg').getBoundingClientRect().top +e.clientY -t.getBoundingClientRect().top; 10 drag.target=t; 11 drag.mouseon="1"; 12 } 13 }); 14 document.addEventListener('mousemove',e=>{ 15 if(drag.mouseon){ 16 drag.target.x.baseVal.value = e.clientX - drag.offsetX; 17 drag.target.y.baseVal.value = e.clientY - drag.offsetY; 18 } 19 }); 20 document.addEventListener('mouseup',()=>{ 21 drag.mouseon=0; 22 }); 23}); 24 25</script> 26<svg height="500" width="500" viewBox="0 0 500 500" draggable="1"> 27<rect x="0" y="0" width=500 height=500 fill="aqua" /> 28<image class="draggable" xlink:href="https://placehold.jp/ff0000/00000/160x138.png?text=fish1" x="100" y="200" width=160 height=138 id="f1" /> 29<image class="draggable" xlink:href="https://placehold.jp/00ff00/00000/160x138.png?text=fish2" x="300" y="150" width=160 height=138 id="f2" /> 30<image class="draggable" xlink:href="https://placehold.jp/0000ff/00000/160x138.png?text=fish3" x="250" y="300" width=160 height=138 id="f3" /> 31</svg>

投稿2023/01/25 09:39

yambejp

総合スコア114839

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

saurinn

2023/01/25 16:13

わ~✨ありがとうございます(^▽^) ばっちり3匹の魚うごきますね!!! 自分のコードと組み合わせてみます^^ それにしてもsvgググったのですがこれってXMLになるんですか? そういえばimgもimageになっていますね(・・; 高度な技を教えていただきほんとにありがたいです!(^^)v✨
guest

0

自己解決

2つの解決策を提案していただけました(⌒∇⌒)

職場の先輩方にもこのページを見ていただいたんですが
ありがたいことにばっちり3匹の魚を泳がせる方法を伝授していただけました!

解決策その1

すっごくシンプルに解決して頂いたコードです。
私はdocument,target,elementを良く理解できていなかったんですが、このコードのおかげでこれらの働きがなんとなく理解できた感じです。

Javascript

1let target = ""; 2// const dragid = document.getElementById('dragid'); 3// const daragid2 = document.getElementById('dragid2'); 4// const daragid3 = document.getElementById('dragid3'); 5 6const dropbox = document.getElementById('dropbox'); 7// let sakana = dragid; 8 9// 追加 10 11/*dragid,dragid2,dragid3をクリックすると変数sakanaに入るようにしたい */ 12//上のdivから下のdivへドラッグアンドドロップ 13window.onload = function () { 14 //変更 sakana.addEventListener('dragstart', function (element) { 15 16 document.addEventListener('dragstart', function (element) { 17 //クリックしたドキュメントを対象にしている。 18 target = element.target; 19 }, false); 20 21 dropbox.addEventListener('dragover', function (element) { 22 element.preventDefault(); 23 }, false); 24 25 dropbox.addEventListener('drop', function (element) { 26 element.preventDefault(); 27 element.target.appendChild(target); 28 drag_fish(); 29 }, false); 30} 31 32//dropboxの中でドラッグ移動 33function drag_fish(){ 34 // draggable(sakana); 35 draggable(target); 36 37 function draggable(target) { 38 target.onmousedown = function () { 39 document.onmousemove = mouseMove; 40 }; 41 document.onmouseup = function () { 42 document.onmousemove = null; 43 }; 44 45 function mouseMove(e) { 46 var event = e ? e : window.event; 47 // 要素の位置座標を取得 48 var clientRect = dropbox.getBoundingClientRect(); 49 50 // ページの左端から、要素の左端までの距離 51 var px = window.pageXOffset + clientRect.left; 52 53 // ページの上端から、要素の上端までの距離、数字はdivのサイズから画像サイズを引いたもの 54 var py = window.pageYOffset + clientRect.top; 55 target.style.position = 'absolute' 56 if (event.clientY > py && event.clientY < py + 234) { 57 target.style.top = event.clientY + 'px'; 58 } 59 if (event.clientX > px && event.clientX < px + 540) { 60 target.style.left = event.clientX + 'px'; 61 } 62 } 63 } 64} 65

ここまでコードがスッキリなることに目から鱗でした!

解決策その2

こちらはeventを利用してめちゃめちゃ高度な技を伝授していただけました!!!
stopPropagationとかmouseMoveとか、すごい!!この動きに対してこの関数がパッと出てくるスキルの高さにただただ脱帽です!
実は私preventDefaultもよく理解できていないので、このコードに出てきた関数を各種ドキュメントを見ながら頑張ってお勉強します!(^^)!

Javascript

1let dragged = null ; 2const dragid = document.getElementById('dragid'); 3const daragid2 = document.getElementById('dragid2'); 4const daragid3 = document.getElementById('dragid3'); 5const dropbox = document.getElementById('dropbox'); 6 7let sakana = [dragid, daragid2, daragid3]; 8 9// 要素の位置座標を取得 10const clientRect = dropbox.getBoundingClientRect(); 11// ページの左端から、要素の左端までの距離 12const px = window.pageXOffset + clientRect.left; 13// ページの上端から、要素の上端までの距離、数字はdivのサイズから画像サイズを引いたもの 14const py = window.pageYOffset + clientRect.top; 15 16sakana.forEach((event) => { 17 18 event.addEventListener('dragstart', event => { 19 dragged = event.target; 20 mouseMove(event); 21 }, false); 22 23 //画像要素の中に他の画像が入り込むのを防ぐ 24 event .addEventListener('drop', event => { 25 event.stopPropagation(); 26 event.preventDefault(); 27 }, false); 28}); 29 30dropbox.addEventListener('dragover', event => { 31 event.preventDefault(); 32}, false); 33 34dropbox.addEventListener('drop', event=> { 35 event.preventDefault(); 36 dragged.parentNode.removeChild(dragged); 37 event.target.appendChild(dragged); 38 //ドロップした際の位置を指定するためにmouseMove 39 mouseMove(event); 40 document.onmouseup = function () { 41 document.onmousemove = null; 42 }; 43}, false); 44 45function mouseMove(event) { 46 const clientY = event.clientY; 47 const clientX = event.clientX; 48 49 dragged.style.position = 'absolute'; 50 if (clientY > py && clientY < py + 234) { 51 dragged.style.top = clientY +'px'; 52 } 53 if (clientX > px && clientX < px + 540) { 54 dragged.style.left = clientX +'px'; 55 } 56} 57 58

マウスの動きに対して魚画像が的確に動いてくれる感じがすごく気持ちいいです!
mouseMoveを使いこなせばドラッグアンドドロップに強くなれそう(^^♪

ありがとうございました

すごく勉強になる回答をいただけたtambejpさん、忙しいのに私のコードをいじっていただいた先輩方にほんとに感謝です!この質問をクリップしていただいたお二方もありがとうございます!

この先。。。

お空に浮かばせた魚をボタンクリックで泳がせる機能を実装する予定です。
また詰まったときはよろしくお願いいたします。

投稿2023/02/05 04:37

saurinn

総合スコア11

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問