问题
I know how to disable draggable when the object is dragged into the correct droppable as you can see below but not when dropped into the wrong droppable. I want the user to not be able to drag again even if the answer is incorrect, which means only one try. I use edge animate which uses a different syntax to get the elements than plain JavaScript but the rest is the same. Below is my code with comments.
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'.
}
});
回答1:
Basically your problem is that by using both accept
and drop
option you make the drop
execute only for accepted elements.
In order to achieve what you want you'll have to use some other way to define that relation between a draggable
and its "correct" droppable
.
E.g. you could add a data attribute to each droppable
that holds the class of the accepted draggable
(say data-accept="drag1"
).
Then you could remove the accept
options from your droppables
and in their drop
handler manually check if the classes match, something like
drop: function( event, ui ) {
if (ui.draggable.hasClass( $(this).data('accept') )) {
// correct match
}
// anyway disable the draggable
ui.draggable.draggable('disable');
}
Here's a demo: JSFiddle
回答2:
After getting some clarification, I offer this alternate solution. With multiple answers and places to drop them, when 1 answer is dropped, that should no longer accept answers, and users should not be able to move that answer further.
Working Example: https://jsfiddle.net/Twisty/crdxcg90/3/
HTML
<div>
<h4>Put the family members in order of youngest to oldest.</h4>
<p class="drag answer" id="1">Homer</p>
<p class="drag answer" id="2">Marge</p>
<p class="drag answer" id="3">Bart</p>
<p class="drag answer" id="4">Lisa</p>
<p class="drag answer" id="5">Maggie</p>
</div>
<div class="dropzone drop1" id="drop-1">Youngest</div>
<div class="dropzone drop2" id="drop-2">2</div>
<div class="dropzone drop3" id="drop-3">3</div>
<div class="dropzone drop4" id="drop-4">4</div>
<div class="dropzone drop5" id="drop-5">Oldest</div>
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;
});
}
});
});
You would need to adjust back to your specific assignments, but this may make it easier on you and be more flexible if the number of answers changes often.
Updated
After looking at your sample, I can see more what you're going for. Hopefully this will help you:
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"
});
});
When the object is dropped, it checks that position in answers1
if the drop matches the answer, we mark it correct and award a coin.
回答3:
Here is the final and correct way it was done in Edge Animate. The way to using data() in Edge Animate is a little different than plain javascript and html. We used it in order to be able to compare the data value with the value of the variable ID. We also used one class for the draggables and added the class in the UI for the draggables that did not have a droppable (distractors) so they could still be dragged and placed in a droppable and act as all the other draggables. Then we added the conditional in the dropEvent function.
//'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
}
来源:https://stackoverflow.com/questions/36203393/how-to-disable-a-draggable-even-if-dropped-into-wrong-droppable