今でしたら jQuery のプラグイン等を使用すれば簡単にドラッグ可能な要素を作ることができます。ですがそこをあえてライブラリを使用せずに作ったらどれだけ大変なのか確かめて見たかったので、ドラッグ可能な要素をひとつ作りました。
下記のコードは 1 辺が 200px の正方形のdiv要素をドラッグ可能にするためのコードです。IE6、IE7、IE8、Firefox、Chromeで動作確認しました。動作デモをこちらで用意しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
<html> <head> <meta charset="UTF-8" /> <script type="text/javascript"> window.onload = function(){ var e = document.getElementById('hoge'); var flag; var clickOffsetTop; var clickOffsetLeft; e.onmousedown = function(evt){ flag = 'on'; evt = (evt) || window.event; clickOffsetTop = evt.clientY - e.offsetTop; clickOffsetLeft = evt.clientX - e.offsetLeft; if(!document.all){ window.getSelection().removeAllRanges(); } } document.onmouseup = function(){ flag = 'off'; } document.onmousemove = function(evt){ evt = (evt) || window.event; if(flag == 'on'){ e.style.top = evt.clientY - clickOffsetTop + 'px'; e.style.left = evt.clientX - clickOffsetLeft + 'px'; } } } </script> <style type="text/css"> #hoge{ width: 200px; height: 200px; text-align: center; border: 1px solid #666666; background: #cccccc; position: absolute; top: 50px; left: 50px; } </style> </head> <body> <div id="hoge"></div> </body> </html> |
ドラッグを可能にするためには3つのイベントを使用します。マウスの左ボタンが押下されたときのonmousedown、マウスの左ボタンが離されたときのonmouseup、マウスが動かされたときのonmousemoveです。
ドラッグしてよいかどうかの判断
何かをドラッグするためにはクリックしたままマウスを動かす必要があります。マウスが離されたら、それまでドラッグされていたものは止まり、マウスを動かしてもそのままであるのが通常の動作です。そのため、マウスボタンが押下されてたらフラグをonに、マウスボタンが離されたらフラグをoffにします。つまり、フラグがonの状態でマウスが動かされたら要素を移動させ、offだったら移動させないようにする必要があります。25行目でflagがonになっていれば要素を移動させる処理を行なっています。
座標の算出
当たり前ですが、ドラッグの最中はドラッグされている対象が動きます。動くということはその要素の座標がマウスが動かされるたびに変わるということです。そのためにはクリックされた座標とドラッグしたときの移動量を知る必要があります。
まず、ドラッグ対象の要素内でどこがクリックされたかを算出します。要素をドラッグしたとしても、ドラッグ対象の左上の座標とクリックされた座標の距離は一定です。この相対的な各座標の距離を算出しているのが14行目と15行目になります。相対的な距離はクリックされた座標からドラッグ対象の左上の座標を引くことで求めることができます。
次に、移動量を求めます。何pxドラッグされたのかはイベントオブジェクトのプロパティにアクセスすることで取得することができます。26行目と27行目のevt.clientX、evt.clientYはマウスのクライアント領域におけるX座標、Y座標が入っています。マウスが動かされるたびに更新されるので、動かした直後の座標から一定の数値であるclickOffsetTop、clickOffsetLeftをそれぞれ引くことで移動させるべき座標が求まります。その座標をマウスが動かされるたびに、ドラッグ対象要素のtopとleftに代入して要素を動かします。
その他の補足
13行目と24行目にevt = (evt) || window.event;と記述がありますが、これはIEではイベントオブジェクトがそのままでは渡されないようなので、evtがundefinedの場合はwindow.eventをイベントオブジェクトとして扱います。
16~18行目のコードはFirefoxで要素をドラッグしようとすると、要素が選択状態になってしまうせいか正しくドラッグできないので、ドラッグ対象要素を選択不可にするためのコードです。