Reputation: 12178
I have a setup where I want to conditionally revert an element that is being dropped
(I tried using the accept
event, but that proved to run far too often for practical purposes. - not only that, its use cancels other events.)
EDIT: its actually not that it runs far too often, but rather that.. when it fires, $(this).attr('id')
becomes incorrect upon revisiting hovered over elements. http://jsfiddle.net/UvByv/1/
For example above:
You will see that the square elements are numbered. When a square is revisited, $(this).attr('id')
apparently stops being updated on a timely basis
*What I am trying to do is to conditionally "toggle droppability", reading the DOM while hovering over an element. it appears that accept
doesn't entirely sync with the rest of the DOM for my purposes. *
The reason is, as you will see with my example, being squares with chess pieces, depending on what square a piece is over at a particular point in time., I might not want to allow a drop. Other times, I would want to.
Upvotes: 3
Views: 273
Reputation: 11696
If I understand this correctly, you want to toggle droppability based not only on whether or not the space is currently occupied, but also if the current move is a valid chess move (after all, some valid chess moves involve one piece taking the place of another). Is this true? If so, I would think using a complex accept
function would, in fact, be the right strategy.
This function receives two pieces of critical information: the piece being dragged (the sole "el" argument) and the space potentially being dragged to (which is the function's this
variable). You noted that the accept
function is called multiple times, and this is by design: as you can see in the jQuery UI source code, when a draggable is being dragged, the accept
function will be evaluated for each droppable space on the board. This means that when you start moving a piece, each droppable space will calculate whether or not it can accept the piece.
I understand that you want to evaluate this "on the fly" as a piece passes over another square, but is the overhead of calculating it in advance causing noticeable performance issues? If not, I would go with accept
.
Edit: I've created a jsFiddle that demonstrates how to use .append to move the piece from square to square: http://jsfiddle.net/58t7L/3/
Edit by Kevin: Accepted because in chat Matt helped to stratify the issue to show that my method of using $(this) in accept is not exactly geared toward how accept is intended to be used. .over: would be for the process I was describing and using, while 'accept' really demands a different process, as it evaluates all droppables at once. Chat link is in comment below
Upvotes: 3