初めてのJavaScript第二版 12章の例題をじっくりやってみる。
初めてのJavaScript第二版 P258 12.3.2 ドラッグ
この例題を考える。
結果の画面からコードを起こせれば合格だと思うので、本書を参考にしながらやってみよう。
オフィシャルのサポートページ(http://www.marlin-arms.com/support/ljs2/index12.php)の例題12-6を参照。
画面を見たうえで、思いついた流れで作ってみよう。(関数名は本と合わせる。)
おそらくいくつか抜けていて動かないと思うので、その場合は本を参照する。
1.script以外のhtml部分を流用する。 2.イベントハンドラを割り当てる。 (ここからは関数を作る。) 3.マウスの位置を補足する。 4.移動するオブジェクトのオフセットを取得する。 5.クリックしている状態を補足する。 6.クリックを離したことを補足する。 7.マウスを動かしたときに画像もが動く関数を作る。(3,4,5,6と組み合わせる) 8.書いてからわかったことを追記する。 9.動かす。
それではやってみよう。
1.script以外のhtml部分を流用する。
中でも、重要なのは枠と画像のidなので、ここではこれだけ書く。(実際には全部必要)
<div id="div1" > <img id="img1" src="../chap09/pictno1.jpg" alt="例題の図" /> </div> (枠はdiv1にcssでつけているのだがそれは省略。)
2.イベントハンドラを割り当てる。
document.onmousedown = mouseDown; //クリックした(押した) document.onmousemove = mouseMove; //マウスの座標が変わった document.onmouseup = mouseUp; //クリックを上げた(指を離した)
3.マウスの位置を補足する。
基本に忠実に、clientX,Yを使う。
//event.clientX,Yの値をMousePointに格納する。 function mousePosition(event){ var x = event.clientX; var y = event.clientY; return new MousePoint(x,y); } function MousePoint(x,y){ this.x = x; this.y = y; }
4.移動するオブジェクトのオフセットを取得する。
画像(id = img1)位置を取得する。
マウスの位置と、offsetの位置を利用する。
element.offsetLeftは、
offsetParent(つまりbody要素だが、今回は=div1要素のはず)の左上の座標を基準とした相対的なX座標。
function getMouseOffset(target, event){ //引数は[object HTMLImageElement],[object MouseEvent]が入る想定 var theEvent = event ? event : window.event; var mousePos = mousePosition(theEvent); //マウスの位置 var x = mousePos.x - target.offsetTop; //マウスのX座標 - img1のX座標 var y = mousePos.y - target.offsetTop; //マウスのY座標 - img1のY座標 return new MousePoint(x, y); }
5.クリックしている状態を補足する。
考えてみると「クリックしている状態」ではなく「ドラッグできる要素(img1)をクリックしている状態か否か」が知りたいので、
onmousedownしたときにimg1上であればオブジェクトを受け取り、それ以外は何もしない。
それによりdocument.getElementById("img1").onmousedownだけ有効とするので、1.で書いた
document.onmousedown = mouseDown;は消して、以下のようにする。
functino makeDraggable(itemid){ //実際はmakeDraggable("img1")と呼ばれることを想定。 if(itemid){ item = document.getElementById(itemid); item.onmousedown = function(theEvent){ //theEventに渡されるのは[object MouseEvent] dragObject = this; //dragObjectはグローバルで宣言する。thisは[object HTMLImageElement] mouseOffset = getMouseOffset(this, theEvent); //mouseOffsetもグローバルで宣言。 return false; //onmousedownをキャンセルするために必要 }; } }
6.クリックを離したことを補足する。
これも、img1を抱えてるときだけ行えば良い。
function mouseUp(Event){ if(dragObject){ //←例ではifで囲まず、常に↓を行っている。 dragObject = null; //dragObjectはグローバル変数として定義が必要。 } }
7.マウスが動く関数を作る。(3,4,5,6と組み合わせる)
dragObjectに何か入ってるときに、正規化されたマウス位置を取りだし、
function mouseMove(event){ var theEvent = event ? event : window.event; var mousePos = mousePosition(theEvent); dragObject.style.position = 'relative'; dragObject.style.left = mousePos.x - mouseOffset.x + "px"; dragObject.style.top = mousePos.y - mouseOffset.y + "px"; //return false; //本書にあったのだが、なぜあるのか分からない。無くても動作する@firefox。 }
8.書いてからわかったことを追記する。
var dragObject = null; //グローバル変数 var mouseOffset = null; //グローバル変数 window.onload = function(){ makeDraggable("img1"); }
9.動かす。
最初はところどころスペルミス等はあったり、動かなかったのだが、少し手直ししたら動いた。
(今まで書いたコードは直した後のもの)
とはいえ、7.のreturn falseが何故必要なのか調べきれていない。(無くても動くことは確認。)
じっくり書いたらすごい時間がかかってしまったので、13章の例題は明日以降に。
綺麗なソースはサポートページ(最初に書いたURL)からどうぞ。殆ど同じですので。
※後ほど修正するかも。その場合は履歴を残す。