Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery draggable - what happens if it is applied twice to an element?

Until recently I had this set up, which was called multiple times:

                $('.rsh')
                    .draggable('destroy')                               
                    .draggable({ blah blah details });

The destroy was there to stop multiple draggable handlers accumulating on the class. New elements are being created by AJAX, and an initial attachment of draggable to the class doesn't touch subsequently created elements.

However, when I updated to version 1.9.2 of jQuery UI, it started giving me this error:

Error: cannot call methods on draggable prior to initialization; attempted to call method 'destroy'

So I removed the destroy line, and it's sweet. Except... I suspect that I may now be adding more and more handlers to the class (which is why the destroy was there in the first place).

I tried this, but it didn't like it:

if ($('.rsh').length) {
    $('.rsh').draggable('destroy'); 
}

Two questions: (1) Will there be more and more handlers attached to the class each time I fire the draggable set up line? (2) If so, any solutions on how to remove them?

like image 716
Nick Avatar asked Dec 16 '22 15:12

Nick


2 Answers

No, there won't be extra handlers bound. jQuery registers the initialized instance to the element and won't create a new instance of the same widget for the same element.

As you're worried about handlers, here's a quick check (jQuery 1.8+ and UI 1.9+):

$('div').draggable();
console.log( $._data($('div')[0], 'events') );
$('div').draggable();
console.log( $._data($('div')[0], 'events') );

Fiddle

As you can see, the attached handlers object is not altered after trying to initialize a new draggable instance on the same element.

edit: Subsequent calls with parameters won't be ignored though, rather they will extend the existing widget as shown on @Jason Sperske's answer.

like image 82
Fabrício Matté Avatar answered Dec 30 '22 10:12

Fabrício Matté


Subsequent calls to .draggable() extend previous calls when attached to the same object (and not replace them as I had originally thought). See this example (extended from Fabrício Matté's) (demo)

<div>foo</div>
<script>
 $('div').draggable({
  start: function () {
    console.log("drag 1");
  }
 });
 console.log($._data($('div')[0], 'events'));
 $('div').draggable({
  stop: function () {
    console.log("drag 2");
  }
 });
 console.log($._data($('div')[0], 'events'));
</script>

In the console.log you see only these messages:

drag 1 <- on start
drag 2 <- on stop
like image 35
Jason Sperske Avatar answered Dec 30 '22 09:12

Jason Sperske