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

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

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

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

Q&A

解決済

2回答

1946閲覧

addEventlistenerの習作としてのdiv要素をドラッグするものの改良

gyojin

総合スコア94

JavaScript

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

0グッド

2クリップ

投稿2015/06/30 09:39

addEventListenerの習作として以下のようなものを作りました
ざっと見て問題点がいくつかありますが
1.ドラッグが早いと移動が追いつかず置いてけぼりになる
2.12行目、13行目のプロパティの設定について同様のやり方が(私が調べた内では)手持ちの書籍、ネット上でみあたらず、いいやり方なのかまずいやり方そもそも違う方法を取るべきなのか判断材料が無い

この2点について改良方法、意見を募集します

lang

1 1 //各divにmousedownをつける 2 2 function addMousedown(moveTarget){ 3 3 for(var i=0;i<moveTarget.length;i++){ 4 4 moveTarget[i].addEventListener("mousedown", 5 5 addMousemoveAndMouseup, 6 6 false); 7 7 } 8 8 } 9 9 //mousedownを感知した場合の処理 10 10 function addMousemoveAndMouseup(e){ 11 11 12 12 e.target.offsetY=e.clientY-e.target.offsetTop; 13 13 e.target.offsetX=e.clientX-e.target.offsetLeft; 14 14 //mousemoveイベントハンドラを付ける 15 15 e.target.addEventListener("mousemove", 16 16 mouseMove, 17 17 false); 18 18 //mouseupイベントハンドラを付ける 19 19 e.target.addEventListener("mouseup", 20 20 removeEvent, 21 21 false); 22 22 } 23 23 function mouseMove(e){ 24 24 var X=e.clientX-e.target.offsetX; 25 25 var Y=e.clientY-e.target.offsetY; 26 26 e.target.style.top=Y+"px"; 27 27 e.target.style.left=X+"px"; 28 28 } 29 29 function removeEvent(e){ 30 30 e.target.removeEventListener("mousemove", 31 31 mouseMove, 32 32 false); 33 33 e.target.removeEventListener("mouseup", 34 34 removeEvent, 35 35 false); 36 36 } 37 37 38 38 window.onload=function(){ 39 39 //rootをcontainerに設定 40 40 var root=document.getElementById("container"); 41 41 42 42 //各divを登録 43 43 var moveTarget=root.getElementsByTagName("div"); 44 44 addMousedown(moveTarget); 45 45 } 46

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

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

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

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

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

guest

回答2

0

ベストアンサー

  1. については、マウスカーソルと要素の相対位置をどこかに記憶しておく必要がある、ということですよね?

DOMエレメントにプロパティを生やすことになるので、ちょっと気持ち悪い感じがしないでも無いですけど、、、代替としてぱっと思いつくのがグローバル変数ぐらいなので、ダメということはないと思います。

もしくは、mouseMove をクロージャーにして、イベントハンドラそのものにその情報を持たせるという案も考えられます。

例えば、次のようにです。

lang

1function addMousedown(moveTarget){ 2 // 略 3} 4 5function addMousemoveAndMouseup(e){ 6 var target = e.target; 7 var offsetY = e.clientY - e.target.offsetTop; 8 var offsetX = e.clientX - e.target.offsetLeft; 9 10 var mouseMove = function (e) { 11 var X = e.clientX - offsetX; 12 var Y = e.clientY - offsetY; 13 target.style.top = Y + "px"; 14 target.style.left = X + "px"; 15 }; 16 17 var removeEvent = function () { 18 document.removeEventListener("mousemove", mouseMove, false); 19 document.removeEventListener("mouseup", removeEvent, false); 20 }; 21 22 document.addEventListener("mousemove", mouseMove, false); 23 document.addEventListener("mouseup", removeEvent, false); 24} 25 26window.onload = function(){ 27 // 略 28}

この方法ならさっきのような dragging などという id を付けたり外したりする必要もありません。イベントハンドラそのものが、ドラッグ中の要素を持っているので。

その代わり、ドラッグの開始時に新しいクロージャーを生成する必要があるので、mousemove や mouseup でイベントの付け外しが必要になります。

投稿2015/07/15 03:39

ngyuki

総合スコア4514

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

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

gyojin

2015/07/17 04:50

二つの質問に両方答えていただいた上にサンプルまで付けて下さってありがとうございます。 PHPに続いてjavascriptをぽちぽち始めてみたのですがオブジェクト指向や言語の構造に関しては言語の参考書とは別の資料が必要だなーと痛感します。
guest

0

  1. については div にイベントハンドラを仕込んでいるため、あまり早くドラッグすると div の枠外までマウスカーソルが移動してしまい、イベントが拾えなくなるからです(ご理解されているっぽいですけど)。

これは document などにイベントハンドラを仕込むようにすれば回避できます。

例えばこんな感じにです。

lang

1function addMousedown(moveTarget){ 2 // 略 3} 4 5function addMousemoveAndMouseup(e){ 6 // もし id が dragging の要素があれば id を引っぺがす 7 var target = document.getElementById('dragging'); 8 if (target) { 9 target.removeAttribute('id'); 10 } 11 12 // ドラッグ中のオブジェクトの id に dragging を設定 13 e.target.setAttribute('id', 'dragging'); 14 15 e.target.offsetY = e.clientY - e.target.offsetTop; 16 e.target.offsetX = e.clientX - e.target.offsetLeft; 17 18 // document にイベントハンドラを設定 19 document.addEventListener("mousemove", mouseMove, false); 20 document.addEventListener("mouseup", removeEvent, false); 21} 22 23function mouseMove(e){ 24 // id が dragging の要素を取り出して処理する 25 var target = document.getElementById('dragging'); 26 if (target) { 27 var X = e.clientX - target.offsetX; 28 var Y = e.clientY - target.offsetY; 29 target.style.top=Y+"px"; 30 target.style.left=X+"px"; 31 } 32} 33 34function removeEvent(e){ 35 // document のイベントハンドラを削除 36 document.removeEventListener("mousemove", mouseMove, false); 37 document.removeEventListener("mouseup", removeEvent, false); 38} 39 40window.onload = function(){ 41 // 略 42}

この例だと mousemove とか mouseup とかのイベントハンドラを付け外しする必要もありませんけどね(^_^;)

投稿2015/07/15 03:24

編集2015/07/15 03:40
ngyuki

総合スコア4514

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問