Here is something interesting about detach() vs remove() in jquery that happened to me.
As we know, remove() removed an element from the DOM wherease thedetach() does the same thing but it keeps all the jquery events bound to the element to which the method is applied to.
I have an application which allows users to upload and validate some files. The form sits in a popup which is triggered by a normal button on the page. When the popup is open users can upload a file (only one) using a input of type file and send it via ajax to the server when they submit the form.
The popup has a close button and when it is pressed the popup was detached using detach() from the DOM and the input field cleared. What happened was that every time I reopened the popup and upload a new file, somehow I ended up with more than one file, the one uploaded plus the other ones I uploaded before (one for each session), unless I ctrl + f5. Specifically, when I pressed the browse button, selected a file from the file system and pressed open, I would get the same file system window again, once, twice, three times, depending on home many times I had so far uploaded a file.
I replaced detach() with remove() and so not only I remove the popup from the DOM when the close button is pressed, but I also remove the associated jquery data from the form/poupup. The result? Everything works fine.
So, the question is, why detach() was misbehaving with file upload? It feels like somehow it stored the amount of times I clicked on the browse button and then representing me with those clicks if you like.

Dani AI

Generated

— good catch. The behavior you saw is the classic symptom of event handlers piling up when a detached node is re-used and your init code runs again. Because the popup was detached (so jQuery kept its handlers/data) and then you re-bound handlers each time you reopened it, clicks on the file control ended up invoking the same logic multiple times — hence multiple file dialogs. was right to point at the remove/detach difference, but here are practical ways to diagnose and fix it.

To inspect whether handlers are stacking, in DevTools try:

// Chrome: select element in Elements panel, then in Console:
getEventListeners($0)

// jQuery (debugging only — internal API):
console.log($._data($('#fileInput')[0], 'events'));

Ways to prevent the duplicate dialogs (pick one or combine):

  • Bind once using delegation so you never re-bind on each open:
    $(document).on('change', '.popup .file-input', handler);
  • Use namespaced events and explicitly remove before re-binding:
    $btn.on('click.upload', handler);
    $btn.off('.upload'); // removes only the upload handlers
  • If you keep using detach for performance, call .off() or .removeData() before detaching, or guard initialization with a data flag so handlers are added only once:
    if (!$popup.data('initialized')) { /* bind handlers */ $popup.data('initialized', true); }
  • If you want a truly fresh form, use .remove() (or replace the input) and reset the file input with form.reset() or $('#fileInput').val('').

Additional notes: avoid clone(true) (it copies events). Repeated detaches that retain handlers can also cause memory growth, so choose remove+recreate or careful unbinding if you need long-lived cleanup.

Recommended Answers

All 3 Replies

thanks, I knew detach() kept the data somehow as opposed to remove(), but in the thread there is a nice example http://jsfiddle.net/L6CEA/ which is in fact self explanatory and helpful and clearly shows how one keeps the jquery data and the other one discards it. That's good to know!

If this is solved, click the box?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.