[Javascript] エレメントをマウスでDRAG移動させるスニペット

2016年9月14日

Javascript テクノロジー プログラミング

ネイティブJSで特定のエレメントをマウスでドラッグするやり方をメモしておくよ。 WEBエンジニアの人と話す時に、この手のプログラムが書けない人が意外と多くいることが判明。 その理由は、jQueryを使えば、プログラミングする必要がないから・・・ よくあるライブラリに頼りすぎてて、根本が理解できていない典型的な使えないエンジニアです。 少なくてもWEBプログラムをやる場合はフロント処理として、イベント処理とエレメントのCSSセットぐらいは理解して、自分でコントロールできるようにしておこう。

構成

ファイル

index.html drag.js

ソース

<html> <head> <title>Element-Drag</title> <style> #box{ position:absolute; border:4px solid red; display:inline-block; width:100px; height:100px; cursor:pointer; } </style> </head> <body> <h1>Element-Drag</h1> <div id="box"></div> <script type="text/javascript" src="drag.js"></script> <script> $$elementDrag.set({target:document.getElementById("box")}); </script> </body> </html> /** * Element Drag * [How-to] * 1. read-library * 2. script-set : $$.elementDrag.set({target:document.getElementById("hoge")}); */ (function(){ var $$ = {}; $$.cache = {}; $$.eventAdd=function(t, m, f){ //other Browser if (t.addEventListener){t.addEventListener(m, f, false)} //IE else{ if(m=='load'){ var body = d.body; if(typeof(body)!='undefined'){body = w;} if((typeof(onload)!='undefined' && typeof(body.onload)!='undefined' && onload == body.onload) || typeof(eval(onload))=='object'){ t.attachEvent('on' + m, function() { f.call(t , w.event); }); } else{f.call(t, w.event)} } else{t.attachEvent('on' + m, function() { f.call(t , w.event); })} } }; $$.set = function(option){ if(!option.target){return} $$.eventAdd(option.target , "mousedown" , $$.mousedown); $$.eventAdd(window , "mouseup" , $$.mouseup); $$.eventAdd(option.target , "mouseout" , $$.mouseout); $$.eventAdd(window , "mousemove" , $$.mousemove); }; $$.mousedown = function(event){ //DRAGフラグ $$.cache.dragFlg = true; //エレメント絶対座標の取得 var pos = $$.pos(event.target); $$.cache.elementPos = pos; //カーソル座標の取得 $$.cache.cursor = { x:event.pageX, y:event.pageY }; }; $$.mouseup = function(event){ //DRAGフラグ $$.cache.dragFlg = false; }; $$.mouseout = function(event){ }; $$.mousemove = function(event){ if(!$$.cache.dragFlg){return} //座標の変更 event.target.style.left = (event.pageX - $$.cache.cursor.x + $$.cache.elementPos.x) + "px"; event.target.style.top = (event.pageY - $$.cache.cursor.y + $$.cache.elementPos.y) + "px"; }; //指定したエレメントの座標を取得 $$.pos = function(e,t){ //エレメント確認処理 if(!e){return;} //途中指定のエレメントチェック(指定がない場合はbody) if(typeof(t)=='undefined' || t==null){ t = document.body; } //デフォルト座標 var pos={x:0,y:0}; do{ //指定エレメントでストップする。 if(e == t){break} //対象エレメントが存在しない場合はその辞典で終了 if(typeof(e)=='undefined' || e==null){return pos;} //座標を足し込む pos.x += e.offsetLeft; pos.y += e.offsetTop; } //上位エレメントを参照する while(e = e.offsetParent); //最終座標を返す return pos; }; window.$$elementDrag = $$; })();

解説

今回のプログラムでは、ブラウザ画面からカーソルが出た時のキャンセル処理や、対象オブジェクトが画面の端に来たらそれ以上移動しないというような処理は入れてなく、マウスをクリックして指が離れずに移動している座標をひたすら追いかけるプログラムです。 デバッグしているブラウザは、mac + GoogleChromeのみです。 無名関数内の変数にエレメントやマウスの座標を固定で出し入れしているのがベタすぎて個人的に気に入ってはいないのですが、移動させるエレメントが1つの場合であれば、このやり方で問題はおきないはず。

応用アイデア

ページ内にある複数のエレメントをマウスでドラッグさせて、WindowsやMacのデスクトップアイコンのようなものも作れるね。 また、移動の際に数ピクセル毎にFITさせると、比較的整理整頓が楽になる積み木やブロックパズルゲームなどを作ることも簡単にできますね。

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。