Bug Tracker

Opened 6 years ago

Closed 5 years ago

Last modified 5 years ago

#13400 closed feature (duplicate)

.replaceWith() with .detach() instead of .remove()

Reported by: anonymous Owned by:
Priority: undecided Milestone: None
Component: unfiled Version: git
Keywords: Cc:
Blocked by: Blocking:

Description

I would like to propose a version of .replaceWith() that doesn't do .remove() but .detach() instead.

The problem is that the .remove() call in .replaceWith() removes all data and events attached to the element. When putting the element back in the DOM at a later time, it is often useful to still have the data/events bound.

See: http://jsfiddle.net/DX3dv/

Change History (10)

comment:1 Changed 6 years ago by dmethvin

Resolution: wontfix
Status: newclosed

It's not a case of just leaving data and events "in place" on the old element. Since you're *replacing* the element, the only way to do this would be to copy the data and events from the replaced element.

Since we've gone seven years without anyone requesting this, I think it's rare enough that you should just manage it in the app, either by using delegated events or re-attaching them.

comment:2 Changed 6 years ago by anonymous

Just for the record, I don't think it's that rare...

The need arises for example when implementing a 'wizard-like' navigation. You need to replace the contents of a node each time 'next' is clicked, but when 'back' is clicked you still want the original contents with their event handlers in place.

comment:3 Changed 6 years ago by jgehrcke@…

Just came across this issue, because I want to toggle content upon click whereas the toggle "switch" is part of the content. In this case, it would be useful to just replace one element with another without losing attached event handlers.

comment:4 Changed 5 years ago by anonymous

I also just came to this. Navigation using scroll fix headings, when the user scrolls to a point header.replaceWith(placeholder) and fix the heading, but event handlers get lost. Had to do header.before(placeholder).detach(). Not the end of the world I suppose.

comment:5 Changed 5 years ago by jameshartig

I think the last comment meant to say the solution is placeholder.insertBefore(header); header.detach();

It doesn't make sense otherwise.

comment:6 Changed 5 years ago by anonymous

I too came across the requirement to keep events en-tacked using replaceWith. It seems as though this would be a very simple fix, no?

...this

jQuery( this ).remove();
parent.insertBefore( elem, next );

... would become

if ( detach ) {
	jQuery( this ).detach();
	parent.insertBefore( elem, next );
}

Then there could be two functions. One for detach and another for the normal replaceWith (both of which call the private function using the detach flag that actually does the work).

comment:7 Changed 5 years ago by steven_ganz

+1 See also #14181.

comment:8 Changed 5 years ago by dmethvin

Resolution: wontfix
Status: closedreopened

comment:9 Changed 5 years ago by dmethvin

Resolution: duplicate
Status: reopenedclosed

Duplicate of #14181.
See the plugin in #14181. There is no reasonable way to add a boolean argument to .replaceWith() so the best solution is a new API, which given the rare need is best done as a plugin.

comment:10 Changed 5 years ago by paulscode

In case anyone arrives here as I did looking for a quick alternative to replaceWith() that keeps attached events, it can be done using a combination of existing functions in the current API:

this:

    old.replaceWith( new );

can be changed to:

    old.before( new ).detach();

Both return a handle to the removed element, so depending on the use case it should be pretty simple to change.

Note: See TracTickets for help on using tickets.