指定したHTML要素をウインドウ内で自由に移動します。最初につかむ要素handleと動かす実体targetを別々に指定します。targetが省略されるとhandleが動く実体となります。ダイアログのタイトルだけをつかんでダイアログ全体を動かすようなときにtargetを指定します。
なお、いきなり対象の要素を動かすと、配置が崩れてみっともないことになるので、一旦半透明のコピーを作ってそれを移動させ、ドロップする段階で実際に本体を移動させています。
以下では、「ブラウザによるイベントの扱いを正規化する」のコードを使ってイベントの扱いを楽にしています。
【サンプルコード】
(function(handle, target) {
if (!target) target = handle;
/* イベントの違いを吸収する */
var fixEvent = function(evt) {
if (!window.event) {
evt.offsetX = evt.pageX;
evt.offsetY = evt.pageY;
var el = evt.target;
while (el) {
evt.offsetX -= el.offsetLeft;
evt.offsetY -= el.offsetTop;
el = el.offsetParent;
}
} else {
evt = window.event;
evt.target = evt.srcElement;
evt.preventDefault = function() { this.returnValue = false; };
evt.stopPropagation = function() { this.cancelBubble = true; };
switch(evt.type) {
case 'click':
case 'mousedown':
case 'mouseup':
case 'mousemove':
evt.which = evt.button==4 ? 3 : evt.button;
evt.pageX = evt.offsetX;
evt.pageY = evt.offsetY;
var el = evt.target;
while (el) {
evt.pageX += el.offsetLeft;
evt.pageY += el.offsetTop;
el = el.offsetParent;
}
break;
case 'keypress':
case 'keydown':
case 'keyup':
break;
}
}
return evt;
}
handle.onmousedown = function(evt) {
evt = fixEvent(evt);
var pos = { x : 0, y : 0 };
var p = target;
while (p) {
pos.x += p.offsetLeft;
pos.y += p.offsetTop;
p = p.offsetParent;
}
var shadow = document.body.appendChild(target.cloneNode(true));
shadow.style.cursor = "move";
shadow.style.opacity = 0.7;
shadow.style.filter = "alpha(opacity=70);"
shadow.style.left = pos.x + "px";
shadow.style.top = pos.y + "px";
shadow.style.position = "absolute";
shadow.style.margin = "0px"; /* 座標のずれを防ぐ */
shadow.dx = evt.pageX - pos.x;
shadow.dy = evt.pageY - pos.y;
document.onmousemove = function(evt) {
evt = fixEvent(evt);
shadow.style.left = (evt.pageX - shadow.dx) + "px";
shadow.style.top = (evt.pageY - shadow.dy) + "px";
evt.stopPropagation();
return false;
};
document.onmouseup = function(evt) {
evt = fixEvent(evt);
shadow.style.cursor = null;
document.onmousemove = null;
document.onmouseup = null;
evt.stopPropagation();
target.style.position = "absolute";
target.style.left = shadow.offsetLeft + "px";
target.style.top = shadow.offsetTop + "px";
shadow.parentNode.removeChild(shadow);
return false;
};
evt.stopPropagation();
evt.preventDefault(); /* テキスト選択を防ぐ */
return false;
}
})(document.getElementById('rectangle'));
【サンプルの実行】 → ここをクリックすると、下の四角形をドラッグ&ドロップできます。
JavaScriptコードスニペットへ