2

div をドラッグ可能にするtheZillion ( http://thezillion.wordpress.com/2012/08/29/javascript-draggable-no-jquery/ ) によるこのスクリプトを見つけました。このスクリプトを使用して、div をクラス名で移動しようとしています。IDではありません。

動作するイベント ハンドラーがありますが、スクリプトを追加するときは動作しません... コンソールにもエラーは表示されません。これを機能させる方法についてのアイデアはありますか?

これは私が持っているコードです:

function wrappmover(){
    var moveEvent = "dice-window-wrapper";
    var addClassArr= document.getElementsByClassName(moveEvent);
    for(var i=0; i<addClassArr.length; i++){
        var addClass = addClassArr[i];
        addClass.addEventListener("click", movewrapp, true);
    }       
    function movewrapp() {
        var classToMove = "dice-window-wrapper";
        var elems = document.getElementsByClassName(classToMove);
        var tzdragg = function(){
            return {
                 startMoving : function(evt){ 
                     evt = evt || window.event;
                     var posX = evt.clientX, 
                     posY = evt.clientY, 
                     a = document.getElementsByClassName(classToMove),
                     divTop = a.style.top,
                     divLeft = a.style.left;
                     divTop = divTop.replace('px','');
                     divLeft = divLeft.replace('px','');
                     var diffX = posX - divLeft, 
                     diffY = posY - divTop; 
                     document.onmousemove = function(evt){ 
                         evt = evt || window.event;
                         var posX = evt.clientX,
                         posY = evt.clientY, 
                         aX = posX - diffX,
                         aY = posY - diffY; 
                         tzdragg.move('elem',aX,aY);
                     }
                 },
                 stopMoving : function(){ 
                    document.onmousemove = function(){}
                 },
                 move : function(divid,xpos,ypos){ 
                     var a = document.getElementById(divid);
                     document.getElementById(divid).style.left = xpos + 'px';
                     document.getElementById(divid).style.top = ypos + 'px';
                 }
            }
        }();
4

1 に答える 1

2

さて、ページにドラッグ可能な要素が必要ですか?

次のコードを見てください (これが実際の例です)。一目瞭然だと思いますが、念のためにコメントもあります。

// Wrap the module in a self-executing anonymous function
// to avoid leaking variables into global scope:
(function (document) {
    // Enable ECMAScript 5 strict mode within this function:
    'use strict';

    // Obtain a node list of all elements that have class="draggable":
    var draggable = document.getElementsByClassName('draggable'),
        draggableCount = draggable.length, // cache the length
        i; // iterator placeholder

    // This function initializes the drag of an element where an
    // event ("mousedown") has occurred:
    function startDrag(evt) {

        // The element's position is based on its top left corner,
        // but the mouse coordinates are inside of it, so we need
        // to calculate the positioning difference:
        var diffX = evt.clientX - this.offsetLeft,
            diffY = evt.clientY - this.offsetTop,
            that = this; // "this" refers to the current element,
                         // let's keep it in cache for later use.

        // moveAlong places the current element (referenced by "that")
        // according to the current cursor position:
        function moveAlong(evt) {
            that.style.left = (evt.clientX - diffX) + 'px';
            that.style.top = (evt.clientY - diffY) + 'px';
        }

        // stopDrag removes event listeners from the element,
        // thus stopping the drag:
        function stopDrag() {
            document.removeEventListener('mousemove', moveAlong);
            document.removeEventListener('mouseup', stopDrag);
        }

        document.addEventListener('mouseup', stopDrag);
        document.addEventListener('mousemove', moveAlong);
    }

    // Now that all the variables and functions are created,
    // we can go on and make the elements draggable by assigning
    // a "startDrag" function to a "mousedown" event that occurs
    // on those elements:
    for (i = 0; i < draggableCount; i += 1) {
        draggable[i].addEventListener('mousedown', startDrag);
    }
}(document));

ブラウザが他のリソースをフェッチするのをブロックしないように、可能な限り近い<script></script>タグでロードまたはラップします。 </body>

実際、コメントを削除すると、非常に小さな関数になります。あなたが提供したウェブサイトのものよりもはるかに小さく、より効率的です。

可能な改善

makeDraggable(selector);匿名ラッパーをwhere selectoris a CSS selectorのようなものに置き換えることを検討してください。そうすれば、次のようなクレイジーなことを実行できます。

makeDraggable('#dragMe, #dragMeToo, .draggable, li:nth-child(2n+1)');

これはdocument.querySelectorAll、 による単純なクラス名検索の代わりに複雑な CSS クエリを実行できる を使用することで実現できますdocument.getElementsByClassName

注意事項

  • ページにスクロールがある場合、ドラッグが壊れているように見えます。scrollX と scrollYによってドラッグされた要素の位置を調整することを検討してください
  • これは明らかに Internet Explorer では機能しません (自分で調べてください)。
  • メモリ リークが発生している可能性があります (プロファイリングとテストが必要です)。

編集:新しいドラッグ可能な要素を追加するためのソリューション

ドラッグ可能な要素をもっと追加したいですか?これに取り組むにはいくつかのアプローチがあります。たとえば、makeDraggable(element);関数を作成し、DOM に追加する要素でそれを呼び出すことができます。もちろんうまくいきますが、別のものを見てみましょう。

ドラッグ可能な要素を探して DOM にクエリを実行し、それらにイベント リスナーを割り当てる代わりに、ドキュメント本体の "mousedown" イベントに1 つだけ割り当ててみませんか。

トリガーされると、イベント オブジェクトには、イベントがディスパッチされたオブジェクトであるターゲット要素(マウスダウンした要素) への参照が含まれます。コードの関連部分は次のようになります。

// Performs a check if the current element is draggable and if yes,
// then the dragging is initiated:
function startDragIfDraggable(evt) {
    // Check if the target element (referenced by evt.target) contains a
    // class named "draggable" (http://stackoverflow.com/questions/5898656/):
    if (evt.target.classList.contains('draggable')) {
        // Invoke startDrag by passing it the target element as "this":
        startDrag.call(evt.target, evt);
    }
}

// Listen for any "mousedown" event on the document.body and attempt dragging
// the target element (the one where "mousedown" occurred) if it's draggable:
document.body.addEventListener('mousedown', startDragIfDraggable);

そして、これが上記のコードの実際の例です。おまけとして、新しいドラッグ可能な要素を DOM に追加するシミュレーションを備えています。

動的に追加されたドラッグ可能な要素をドラッグできることに加えて、このアプローチにより、大量のイベント リスナーを大量の要素に割り当てる必要がなくなるため、メモリを節約することもできます。ただし、開発中のアプリケーションが非常にクリックを多用する場合 (ゲームなど) は、クリックごとにチェックが行われるため、CPU を少し浪費する可能性があります。

于 2013-02-05T00:49:59.983 に答える