| 概 要 |
少し前に jQuery UI “Sortable” を使って、<li>,<tr>,<div> 等の要素を並び替えるプログラムを作りました。最近作っていたお絵描きツールで編集した写真を登録し、並び替えたりすることを想定していました。
お絵描きツールの方がある程度出来てきたので、実際に写真を登録し、並び替える方法を考えようとすると再編集する時の呼び出し方法、“Sortable”で扱える最大写真枚数、写真が多い場合にページを分けるなどいろいろと考える様になり、具体的検証もしないまま時間が過ぎてしまいました。
そんな中で、要素をドラッグアンドドロップで移動させるという記事を見て、jQuery に頼らない方法を私なりに検討しています。これまでの確認内容を整理しておきたいと思います。
参考までに、下記がズーム機能を付与したお絵描きツールへのリンクです。お絵描き機能とズーム機能を統合し、それぞれ僅かながらも改良しています。
(→ズーム機能付きのお絵描きツール)
| ドラッグによる要素移動 |
jQuery に頼らずドラッグアンドドロップで要素を並び替える為には、先ずはドラッグアンドドロップで要素を任意の位置に移動出来る様にする必要があります。先ずは第一ステップの移動方法について検討しました。次の図が今回のテストプログラムの実行状況です。ページを開いた初期状態で横方向に並んだ6つの要素をマウス操作で移動させることができます。
(→ドラッグによる要素移動テストプログラム)

| テストプログラム |
今回のプログラム(html+JavaScript)を次に示します。
ページ読込完了後、行番77で “init_chk()” (行番25~27) 経由で “get_window_info()” (行番55~72) を呼び出します。
ここでは、行番79~84で配置している〈div〉要素を取得し、各要素に対し座標設定,ID番号表示等を行い初期配置します。
初期配置後、各マウスイベント発生時にイベントが発生した要素に対して座標更新を行うことで要素を移動させます。
具体的には、まず行番30~37のマウスダウンイベント発生(クリック)時に行番32の “event.target.id” により対象要素のID番号を取得します。次に行番40~47のマウスムーブイベント発生(ドラッグ操作)時に、取得したIDの要素座標を設定することで要素を移動させます。行番50のマウスアップイベント発生時には、ID番号,操作フラグ(“mv_fg”)を初期化し、一連の移動処理を完了します。
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>DRAG & DROP</title>
<style>
* { margin:0; }
.draw_info th, .draw_info td { border:solid 1px #000000; text-align:center; vertical-align:middle; }
.draw_info { border: solid 1px #000000; border-collapse:collapse; margin:5px 10px;}
.div_dragbl { cursor:move; position:absolute; }
</style>
<script type="text/javascript">
var mv_fg="";
var mvs_x=0; var mvs_y=0;
var tgt_id_no; var z_idx_ini=100;
var X_STT_P=0; var Y_STT_P=100;
var img_wdt=150; var img_hgt=120;
function init_chk(){
get_window_info() ;
}
// ◆マウスダウン◆
window.onmousedown = function(e) {
mv_fg = "true" ; tgt_id_no = event.target.id ; z_idx_ini = z_idx_ini + 1 ;
document.getElementById(tgt_id_no).style.zIndex = z_idx_ini ;
mvs_x = event.clientX - parseInt(document.getElementById(tgt_id_no).style.left.replace("px","")) ;
mvs_y = event.clientY - parseInt(document.getElementById(tgt_id_no).style.top.replace("px","")) ;
}
// ◆マウスムーブ◆
window.onmousemove = function(e) {
if(mv_fg == "true") {
var cur_x = event.clientX - mvs_x ; var cur_y = event.clientY - mvs_y ;
document.getElementById(tgt_id_no).style.left = cur_x + "px" ;
document.getElementById(tgt_id_no).style.top = cur_y + "px" ;
}
}
// ◆マウスアップ◆
window.onmouseup = function(e) { mv_fg = "false" ; tgt_id_no = "" ; }
// ◆ウィンドウリサイズ◆
window.onresize = function(e) { get_window_info() ; }
function get_window_info(){
var sW = window.innerWidth ; var sH = window.innerHeight ;
var elm_div = document.getElementById("draggable_div") ;
var rect = elm_div.getBoundingClientRect() ;
Y_STT_P = Math.ceil(rect.top/10) + 20 ;
X_STT_P = Math.ceil(rect.left/10) + 20 ;
var drg_elm=document.getElementsByClassName("div_dragbl");
for(var i=0 ; drg_elm.length > i ; i++){
drg_elm[i].style.top = Y_STT_P + "px" ;
drg_elm[i].style.left = X_STT_P + i * img_wdt + "px" ;
drg_elm[i].style.width = img_wdt + "px" ;
drg_elm[i].style.height = img_hgt + "px" ;
drg_elm[i].style.zIndex = z_idx_ini ;
drg_elm[i].innerHTML = drg_elm[i].id ;
}
}
</script>
</head>
<body onLoad="init_chk()">
<div id="draggable_div" style="position:relative ; clear:both;">
<div class="div_dragbl" id="000001" style="left:0px; top:0px; background-color:blue;"></div>
<div class="div_dragbl" id="000002" style="left:0px; top:0px; background-color:red;"></div>
<div class="div_dragbl" id="000003" style="left:0px; top:0px; background-color:green;"></div>
<div class="div_dragbl" id="000004" style="left:0px; top:0px; background-color:aqua;"></div>
<div class="div_dragbl" id="000005" style="left:0px; top:0px; background-color:yellow;"></div>
<div class="div_dragbl" id="000006" style="left:0px; top:0px; background-color:pink;"></div>
</div>
</body>
</html>
| まとめ |
次回は、ウィンドウサイズを検出し、水平方向に要素がはみ出さない様に複数行にして配列させる方法を検討したいと思います。