サイトマップ

JavaScriptコードスニペット:要素をマウスで動かす

指定した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コードスニペット

 
research/1308701479.txt · 最終更新: 2011/07/08 18:09 by Kazuyuki Matsuda
特に明示されていない限り、本サイトの内容は次のライセンスに従います:Copyright(C) 2011 Shorindo, Inc. All Rights Reserved
Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki