22

ユーザーがいくつかのアイテム (div の 1 つのアイテム) をページ上の他の div にドラッグできる Web サイトを構築しようとしています。これはテーブルなどではなく、ページのどこかに div があるだけです。

html5 のドラッグ アンド ドロップではうまく機能しますが、今はモバイル デバイスでこれを実行しようとしています。アイテムを div にドラッグし、そこにドロップして、このドロップゾーンをブロックできます。また、この要素を別の div またはページ上の別の場所にドラッグすることもできます (ドロップ可能な領域は、div が最初にドロップされたときにのみ機能します)。また。

このドロップゾーンへのドロップを再度有効にするにはどうすればよいですか?

また、2 つの div を別の div にドラッグした場合、2 つの div の位置を変更することは可能ですか?

私のコードの関連部分は次のとおりです。

<script type="text/javascript">
$ (init);
function init() {
    $(".dragzones").draggable({
        start: handleDragStart,
        cursor: 'move',
        revert: "invalid",
    });
    $(".dropzones").droppable({
        drop: handleDropEvent,
        tolerance: "touch",              
    });
}
function handleDragStart (event, ui) {}       
function handleDropEvent (event, ui) {
    $(this).droppable('disable');
    ui.draggable.position({of: $(this), my: 'left top', at: 'left top'});
    ui.draggable.draggable('option', 'revert', "invalid");
}
</script>
<body>
<div id="alles">
<div class="dropzones" id="zone1"><div class="dragzones" id="drag1">Item 1</div></div>
<div class="dropzones" id="zone2"><div class="dragzones" id="drag2">Item 2</div></div>
<div class="dropzones" id="zone3"><div class="dragzones" id="drag3">Item 3</div></div>
<div class="dropzones" id="zone4"><div class="dragzones" id="drag4">Item 4</div></div>
    <div class="dropzones" id="zone11"></div>
    <div class="dropzones" id="zone12"></div>
    <div class="dropzones" id="zone13"></div>
    <div class="dropzones" id="zone14"></div>   
</div>
</body>

編集: これが現在作業中のページです: Drag&Drop Task

4

4 に答える 4

24

これが実際の例です: http://jsfiddle.net/Gajotres/zeXuM/

ここですべての問題が解決されると思います。

  • ドロップ作品の有効化/無効化
  • 返される要素が他の要素の下にドロップされなくなりました
  • 返す要素が非表示/削除されなくなりました
  • より良い要素の配置 (見栄えが良くなります)
  • モバイル デバイスで動作します (Android 4.1.1 Chrome および iPhone でテスト済み)。

使用されるjQueryコードは次のとおりです。

$(document).on('pageshow', '#index', function(){       
    $(".dragzones").draggable({
        start: handleDragStart,
        cursor: 'move',
        revert: "invalid",
    });
    $(".dropzones").droppable({
        drop: handleDropEvent,
        tolerance: "touch",              
    });
});

function handleDragStart (event, ui) { }

function handleDropEvent (event, ui) {
    if (ui.draggable.element !== undefined) {
        ui.draggable.element.droppable('enable');
    }
    $(this).droppable('disable');
    ui.draggable.position({of: $(this),my: 'left top',at: 'left top'});
    ui.draggable.draggable('option', 'revert', "invalid");
    ui.draggable.element = $(this);
}

    // This is a fix for mobile devices

/iPad|iPhone|Android/.test( navigator.userAgent ) && (function( $ ) {

var proto =  $.ui.mouse.prototype,
_mouseInit = proto._mouseInit;

$.extend( proto, {
    _mouseInit: function() {
        this.element
        .bind( "touchstart." + this.widgetName, $.proxy( this, "_touchStart" ) );
        _mouseInit.apply( this, arguments );
    },

    _touchStart: function( event ) {
         this.element
        .bind( "touchmove." + this.widgetName, $.proxy( this, "_touchMove" ) )
        .bind( "touchend." + this.widgetName, $.proxy( this, "_touchEnd" ) );

        this._modifyEvent( event );

        $( document ).trigger($.Event("mouseup")); //reset mouseHandled flag in ui.mouse
        this._mouseDown( event );

        //return false;           
    },

    _touchMove: function( event ) {
        this._modifyEvent( event );
        this._mouseMove( event );   
    },

    _touchEnd: function( event ) {
        this.element
        .unbind( "touchmove." + this.widgetName )
        .unbind( "touchend." + this.widgetName );
        this._mouseUp( event ); 
    },

    _modifyEvent: function( event ) {
        event.which = 1;
        var target = event.originalEvent.targetTouches[0];
        event.pageX = target.clientX;
        event.pageY = target.clientY;
    }

});

})( jQuery );

この例で使用されている touchFix プラグインの元の作成者は、Oleg Slobodskoiです。

于 2013-03-18T11:33:21.900 に答える
3

編集:

ドロップが成功するたびに、最後のドロップ オブジェクトをドラッグ可能なオブジェクトに保存できます。そのため、ドラッグ可能オブジェクトが別のドロップ オブジェクトに移動すると、前のドロップ オブジェクトのドロップ可能オブジェクトを有効にすることができます。

下記参照:

handleDropEventを次のように変更してみてください。

function handleDropEvent(event, ui) {
    if (ui.draggable.lastDropObject !== undefined) {
        ui.draggable.lastDropObject.droppable('enable');
    }
    var dropObject = $(this);
    dropObject.droppable('disable');
    ui.draggable.position({
        of: $(this),
        my: 'left top',
        at: 'left top'
    });
    ui.draggable.draggable('option', 'revert', "invalid");
    ui.draggable.lastDropObject = dropObject;
}

ソースコードに基づく完全な動作例:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

    <head>
        <title>Drag & Drop with jQuery</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <meta name="title" content="" />
        <meta name="keywords" content="" />
        <meta name="description" content="" />
        <link href="http://www.didaktik.physik.uni-muenchen.de/forschung/elektronenbahnen/Betaversion/Tests/Styletest.css" rel="stylesheet" type="text/css" />
        <script type="text/javascript" src="http://www.didaktik.physik.uni-muenchen.de/forschung/elektronenbahnen/Betaversion/Tests/../Alle Seiten/JS/jquery.js"></script>
        <script type="text/javascript" src="http://www.didaktik.physik.uni-muenchen.de/forschung/elektronenbahnen/Betaversion/Tests/../Alle Seiten/JS/jquery-ui-1.8.23.custom.min.js"></script>
        <script type="text/javascript" src="http://www.didaktik.physik.uni-muenchen.de/forschung/elektronenbahnen/Betaversion/Tests/../Alle Seiten/JS/jquery.ui.touch-punch.min.js"></script>
        <script type="text/javascript">
            var test;
            $(init);

            function init() {
                $(".dragzones")
                    .draggable({
                    start: handleDragStart,
                    cursor: 'move',
                    revert: "invalid"
                });
                $(".dropzones")
                    .droppable({
                    drop: handleDropEvent,
                    tolerance: "touch",
                });
            };

            function handleDragStart(event, ui) {}

            function handleDropEvent(event, ui) {
                if (ui.draggable.lastDropObject !== undefined) {
                    ui.draggable.lastDropObject.droppable('enable');
                }
                var dropObject = $(this);
                dropObject.droppable('disable');
                ui.draggable.position({
                    of: $(this),
                    my: 'left top',
                    at: 'left top'
                });
                ui.draggable.draggable('option', 'revert', "invalid");
                ui.draggable.lastDropObject = dropObject;
            }



            function check() {
                var i = 1;
                var richtige = 0;
                while (i <= 10) {
                    var j = i + 10;
                    if (document.getElementById('zone' + j)
                        .innerHTML.search('drag' + i + '"') == 27) {
                        document.getElementById('zone' + j)
                            .style.border = '2px solid green';
                        richtige++;
                    } else {
                        document.getElementById('zone' + j)
                            .style.border = '2px solid red';
                    }
                    i++;
                    alert(document.getElementById(zone + j)
                        .innerHTML);
                };
            }
        </script>
    </head>

    <body>
        <div id="alles">
            <div id="hintergrundbildZuordnungsaufgaben">
                <img src="http://www.didaktik.physik.uni-muenchen.de/forschung/elektronenbahnen/Betaversion/Tests/../E-Feld/Bilder/Versuchsaufbau-Elektronenablenkroehre-unbeschriftet.png" width="740">
            </div>
            <div class="dropzones" id="zone1">
                <div class="dragzones" id="drag1">Item 1</div>
            </div>
            <div class="dropzones" id="zone2">
                <div class="dragzones" id="drag2">Item 2</div>
            </div>
            <div class="dropzones" id="zone3">
                <div class="dragzones" id="drag3">Item 3</div>
            </div>
            <div class="dropzones" id="zone4">
                <div class="dragzones" id="drag4">Item 4</div>
            </div>
            <div class="dropzones" id="zone5">
                <div class="dragzones" id="drag5">Item 5</div>
            </div>
            <div class="dropzones" id="zone6">
                <div class="dragzones" id="drag6">Item 6</div>
            </div>
            <div class="dropzones" id="zone7">
                <div class="dragzones" id="drag7">Item 7</div>
            </div>
            <div class="dropzones" id="zone8">
                <div class="dragzones" id="drag8">Item 8</div>
            </div>
            <div class="dropzones" id="zone9">
                <div class="dragzones" id="drag9">Item 9</div>
            </div>
            <div class="dropzones" id="zone10">
                <div class="dragzones" id="drag10">Item 10</div>
            </div>
            <div class="dropzones" id="zone11"></div>
            <div class="dropzones" id="zone12"></div>
            <div class="dropzones" id="zone13"></div>
            <div class="dropzones" id="zone14"></div>
            <div class="dropzones" id="zone15"></div>
            <div class="dropzones" id="zone16"></div>
            <div class="dropzones" id="zone17"></div>
            <div class="dropzones" id="zone18"></div>
            <div class="dropzones" id="zone19"></div>
            <div class="dropzones" id="zone20"></div>
            <button id="check" value="Check" onclick="check()">Check</button>
        </div>
    </body>

</html>

これが役立つことを願っています。

于 2013-03-16T10:38:20.647 に答える
1

これは私が得た限りです:

$ (init);
function init() {
    $(".dragzones").draggable({
        start: handleDragStart,
        cursor: 'move',
        revert: 'invalid',
        opacity: .5,
    });
    $(".dropzones").droppable({
        drop: handleDropEvent,
        tolerance: "touch",
        out: handleDropRemove
    });

    //prevents dragging to filled default droppables on start
    $(".dropzones").each(function(){
    if ($(this).html().length) { 
        $(this).addClass('taken'); 
    }
    });
}



function handleDragStart (event, ui) {} 
function handleDropRemove(event, ui) {
        //allows drop after removal
       $(this).removeClass('taken');
}      
function handleDropEvent (event, ui) {
   if ($(this).hasClass('taken')) {
       //rejects drop if full
        ui.draggable.draggable('option', 'revert', true);
    } else {
        //accepts drop if enpty
        ui.draggable.position({of: $(this), my: 'left top', at: 'left top'});
        $(this).addClass('taken');
   }
}

Working Demo Here

まだ整理しようとしている問題がいくつかあります。カーソルがいっぱいになったときにドロップゾーンの一番下にカーソルが当たった場合、 out 関数が呼び出されているようです。私はそれを防ぐ方法を理解できないようです。

于 2013-03-16T02:17:03.757 に答える
1

「例」リンクは正しく機能しているように見えます。しかし、私はあなたの問題に対する一般的な解決策を提供したいと思います.

基本的にdropzoneのステータスを見ます。ユーザーがアイテムをドロップすると、ドロップゾーンが利用可能かどうかを確認します。設定されていない場合は、「元に戻す」true。

function handleDropEvent (event, ui) {
    if ($(this).hasClass('occupied')) {
        ui.draggable.draggable('option', 'revert', true);
        return false;
    }
    $(this).append(ui.draggable);
    ui.draggable.position({of: $(this), my: 'left top', at: 'left top'});
    ui.draggable.css('z-index', 0);
    setTimeout(validateDropzones, 0);
}

完全な動作例はこちら: http://jsfiddle.net/jaygiri/SRPm2/

ありがとう。

于 2013-03-15T23:20:50.543 に答える