2

以下の関数を使用してdivをドラッグすると問題が発生します。何らかの理由で、ページ上のコンテンツ(画像やテキストのブロックなど)上でdivをドラッグすると遅れます。

奇妙な部分は、このラグが左から右にドラッグするときに発生せず、上から下にのみ発生することです。

この関数の垂直方向の遅れを取り除く方法はありますか?

function enableDragging(ele) {
    var dragging = dragging || false,
        x, y, Ox, Oy,
        current;
    enableDragging.z = enableDragging.z || 1;
    var grabber = document.getElementById("wrapper");
    grabber.onmousedown = function (ev) {
        ev = ev || window.event;
        var target = ev.target || ev.srcElement;
        current = target.parentNode;
        dragging = true;
        x = ev.clientX + 2;
        y = ev.clientY + 2;
        Ox = current.offsetLeft;
        Oy = current.offsetTop;
        current.style.zIndex = ++enableDragging.z;

        document.onmousemove = function (ev) {
            ev = ev || window.event;
            if (dragging == true) {
                var Sx = parseFloat(ev.clientX) - x + Ox;
                var Sy = parseFloat(ev.clientY) - y + Oy;
                current.style.left = Math.min(Math.max(Sx, Math.min(viewport().width - Sx, 0)), viewport().width - current.offsetWidth) + "px";

                current.style.top = Math.min(Math.max(Sy, Math.min(viewport().height - Sy, 0)), viewport().height - current.offsetHeight) + "px";
            }
        }

        document.onselectstart = function () {
            return false;
        };

        document.onmouseup = function (ev) {
            ev = ev || window.event;
            dragging && (dragging = false);
            if (ev.preventDefault) {
                ev.preventDefault();
            }
        }

        document.body.style.MozUserSelect = "none";
        document.body.style.cursor = "default";

        return false;
    };
}

function viewport() {
    var e = window
    , a = 'inner';
    if ( !( 'innerWidth' in window ) ) {
        a = 'client';
        e = document.documentElement || document.body;
    }
    return { width : e[ a+'Width' ] , height : e[ a+'Height' ] }
} 
4

1 に答える 1

1

私はフィドルを置いて、ここにデモを作成しました: http://jsfiddle.net/N6A4q/var grabber = ele; (テスト 用に処理するために変更を加えたことに注意してください。

cssの配置によって動作が遅くなることに気付きました。
おそらく、問題には値のキャッシュなどの最適化が必要になる可能性があります。

:
current.style.top = Math.min(Math.max(Sx, Math.min(viewport().height - Sx, 0)), viewport().height - current.offsetWidth) + "px";

で改善できます

var viewportHeight = viewport.height();
current.style.top = Math.min(Math.max(Sy, Math.min(viewportHeight - Sy, 0)), viewportHeight - current.offsetHeight) + "px";

ブラウザのリペイント/フローに関する良い読み物は次のとおりです。 http://www.phpied.com/rendering-repaint-reflowrelayout-restyle/

リンクのアドバイス:

たとえば、次のようにスタイルをすばやく連続して (ループで) 設定および取得することはお勧めできません。

// いいえ、いいえ!
el.style.left = el.offsetLeft + 10 + "px";

読み書きが簡単だからです。

于 2013-03-09T11:47:52.557 に答える