即使掉入错误的droppable,如何禁用draggable

我知道如何在将对象拖入正确的droppable时禁用draggable,如下所示,但是当放入错误的droppable时则不会。 我希望用户即使答案不正确也无法再次拖动,这意味着只有一次尝试。 我使用边缘动画,它使用不同的语法来获取元素而不是普通的JavaScript,但其余的是相同的。 以下是我的评论代码。

for(j=0;j<35;j++){ sym.$(answers1[j]).addClass('drag'+j); sym.$('.drag'+j).draggable({ //revert: "invalid" // I do not want revert in any case stop: function(){ $(this).draggable('disabled'); // will disable when dropped anywhere //I want only when into the wrong droppable - //so almost good but not quite right. } }); sym.$(droppables[j]).droppable({ accept: ".drag"+j, drop: function(event,ui){ ui.draggable.draggable( 'destroy' ); // the correct answer is disabled //I could have used 'disabled' here since it does the same as 'destroy'. } }); 

基本上你的问题是,通过同时使用acceptdrop选项,你只能对接受的元素执行drop

为了达到你想要的效果,你必须使用其他方法来定义draggable和它的“正确” droppable之间的关系。

例如,你可以为每个droppable添加一个data属性,该droppable包含接受的draggable类(比如data-accept="drag1" )。 然后你可以从droppables删除accept选项,并在drop handler中手动检查类是否匹配,例如

 drop: function( event, ui ) { if (ui.draggable.hasClass( $(this).data('accept') )) { // correct match } // anyway disable the draggable ui.draggable.draggable('disable'); } 

这是一个演示: JSFiddle

在得到一些澄清之后,我提供了这种替代解决方案。 有多个答案和地点可以删除它们,当1个答案被删除时,它应该不再接受答案,用户不应该再进一步移动答案。

工作示例: https : //jsfiddle.net/Twisty/crdxcg90/3/

HTML

 

Put the family members in order of youngest to oldest.

Homer

Marge

Bart

Lisa

Maggie

Youngest
2
3
4
Oldest

CSS

 .drag { background: #ccc; padding: 3px; width: 60px; text-align: center; margin: 2px; } .dropzone { width: 100px; height: 50px; background: #0f0; float: left; text-align: center; margin: 2px; } .answered { background: #cfc; } 

JQuery的

 $(function() { $(".answer").draggable({ revert: "invalid" }); $(".dropzone").droppable({ drop: function(e, ui) { $(e.target).addClass("answered"); ui.draggable.draggable("destroy"); $(this).droppable("option", "accept", function() { return false; }); } }); }); 

您需要调整回特定的作业,但如果答案数量经常变化,这可能会使您更容易,并且更灵活。

更新

看完你的样本后,我可以看到更多你想要的东西。 希望这会对你有所帮助:

https://jsfiddle.net/Twisty/crdxcg90/6/

 var answers1 = [1, 3, 5]; var coins = 0; $(function() { $(".answer").draggable({ revert: "invalid" }); $(".dropzone").droppable({ drop: function(e, ui) { $(e.target).addClass("answered"); var t = parseInt($(e.target).attr("id").substring(5)); var a = parseInt(ui.draggable.attr("id")); if (answers1[t] === a) { $(e.target).addClass("correct"); coins++; } ui.draggable.draggable("destroy"); $(this).droppable("option", "accept", false); $("#coins").html(coins); }, tolerance: "fit" }); }); 

当对象被删除时,它会在answers1检查该位置,如果下降与答案匹配,我们将其标记为正确并奖励硬币。

这是在Edge Animate中完成的最终和正确的方法。 在Edge Animate中使用data()的方法与普通的javascript和html略有不同。 我们使用它是为了能够将数据值与变量ID的值进行比较。 我们还为draggables使用了一个类,并在UI中为没有droppable的draggables添加了类(distractors),因此它们仍然可以被拖动并放置在droppable中并充当所有其他draggables。 然后我们在dropEvent函数中添加了条件。

 //'level1-D','level1-E','level1-F' added the drag class in the UI for distractors. var answers1 = [ 'level1-A','level1-B','level1-C', 'level2-A','level2-B','level2-C', 'level3-A','level3-B','level3-C', 'level4-A','level4-B', 'level5-A','level5-B','level5-C', 'level6-A','level6-B','level6-C', 'level7-A','level7-B','level7-C','level7-D', 'level8-A','level8-B','level8-C','level8-D','level8-E', 'level9-A','level9-B','level9-C', 'level10-A','level10-B','level10-C', ]; var droppables = [ 'dp0' ,'dp1' ,'dp2' ,'dp3' ,'dp4' ,'dp5' ,'dp8','dp6','dp7','dp9', 'dp10','dp13','dp11','dp12','dp15','dp16','dp14','dp19','dp17','dp20', 'dp18','dp23','dp22','dp21','dp25','dp24','dp27','dp26','dp28','dp29','dp30','dp31' ]; for(j=0;j<32;j++){ // draggables sym.$(answers1[j]).addClass('drag'); // droppables sym.$(droppables[j]).droppable({ accept:'.drag', drop: dropEvent }).data('answer', answers1[j]); // use data to be able to compare gives the same name as the draggables }// end for loop sym.$('.drag').draggable({ revert : "invalid" }); k=0; function dropEvent(event, ui){ ui.draggable.draggable('option', 'revert' , false ); ui.draggable.draggable('option','disabled', true ); ui.draggable.position( { of: $(this), my: 'center', at: 'middle' } ); ID = ui.draggable.attr("id").replace('Stage_',''); if(ID == $(this).data('answer')){ // retrieve the data info and compare to ID k++; sym.getSymbol("meter").play(); sym.getSymbol("coinAnimation").play(0); sym.$(ID + '-result').css({'opacity':1.0}); sym.$("boxScore").html(k); sym.$("score").html(k+'/32'); if (music.paused ) { correct.pause(); } else { correct.currentTime = 0; correct.play(); } }// end if }