Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
pakl

Draggable: jQuery.empty() does not work when div is draggable

Recommended Posts

I'm using a container div that I re-use when populating with different items. That div is also a draggable.

 

Interestingly doing this:

$(container).empty();
//add new content to container

//recreate draggable
var draggable = Draggable.get(container);
if (draggable != null) {
  draggable.kill();
}
//create new draggable here

will result in the draggable to malfunction in that it suddenly contains both the old and new content which I really don't understand since the container.empty() call should clear all old content of it.

 

Doing this:
 

var draggable = Draggable.get(container);
if (draggable != null) {
	draggable.kill();
}
$(container).empty();
//add new content
//recreate draggable

works just fine but it's awkward that I can't rely on $(container).empty to actually clear the div properly.

 

How is it possible that .empty() doesn't remove content properly inside a draggable?

 

 

Link to comment
Share on other sites

Is there a suggested way to re-use/re-create a draggable container?

Link to comment
Share on other sites

Hello pakl and Welcome to the GreenSock Forum!

 

Keep in mind that jQuery empty() method is really buggy, and does not always work as expected. It sometimes does not remove binded events or does not completely remove its children. You might have to use the jQuery cleanData() method to remove all contents and DOM events that are still in memory. cleanData() is an undocumented jQuery method that is only found in the JQuery source. But sometimes its best to just use the jQuery remove() method to make sure the whole element and any binded events are removed and sent to garbage collection. But sometimes its best to just unbind the events before removing the element from the DOM with removeEventListener() which is a native JS method.

 

:)

  • Like 3
Link to comment
Share on other sites

Jonathan's advice seems perfectly sound (as usual).

 

It would be nice to see a basic demo of this but I suspect the browser is preventing the element from being truly removed if Draggable still has eventListeners applied to it. I don't know much about jQuery.empty() but I'm not entirely sure it can or does remove eventListeners that weren't set via jQuery(). Using draggable.kill() is the best way to clean up your Draggable stuff and make it eligible for garbage collection / removed from memory.

  • Like 3
Link to comment
Share on other sites

Thanks for the input. For what it's worth, here is the hack I used to get around this issue without having to touch my code base too much:

(function () {
	var originalEmpty = jQuery.fn.empty;
	jQuery.fn.empty = function () {
		var draggable = Draggable.get(this);
		if (draggable != null) {
			draggable.kill();
		}
		return originalEmpty.apply(this, arguments);
	};
})();

It just overrides the jQuery.empty method, checks for a draggable and kills it before calling the original empty logic of jQuery.

Seems to work fine so far. Obviously this is a hack very specific to how I use both jQuery and draggable in this project.

 

I just haven't ever encountered any issues with empty before so was suspecting draggable of doing something unusual here.

Link to comment
Share on other sites

What I don't understand is why you are killing it if you want to use it again. There's no need to for that. Just reuse it. If you want to change to something, look at its vars object. Everything you passed in is on it. You can also disable it if you don't need to use it immediately.

 

And posting code is pretty much pointless as it never tells the whole story. I can't reproduce the issue based on your description.

See the Pen 69a827430af1001d4e9565ba6e3f9203?editors=0010 by osublake (@osublake) on CodePen

Link to comment
Share on other sites

Thanks for trying to reproduce it! I'm not sure why but if you change your draggable construction options to:

type: 'scrollTop',
onDragEnd: restart,
edgeResistance: 0.75,
throwProps: true,
onPress:function(){},
onRelease:function(){}

you will see the issue as every time you drag items are added to the container.

 

I need to re-create the draggable because the number of items varies and updating the contents of a draggable doesn't seem to work flawlessly.

Link to comment
Share on other sites

Ah. Using scrollTop definitely explains a lot. I think the copy is a result of the scroll proxy object Draggable creates. Maybe @GreenSock can explain how to reuse those type of Draggables. I'm seeing some method to calibrate it in the source code,  but I've never used it before.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×