JSFiddle - React, Tailwind, and code Playground

HTML

<ul>
    <li>test 1</li>
    <li id="testParent">test 2<span id="testChild">nested</span><span>also nested</span></li>
    <li id="testUntrack">test 3<span>also nested</span></li>
</ul>

JavaScript

// Create a scope so that our variables are not global
(function(){
    /**
     * True while unbinding removal tracking
     */
    var isUntracking = false;
    
    /**
     * A reference that is only known here that nobody else can play with our special event.
     */
    var dummy = function(){};
    
    /**
     * Special event to track removals. This could have any name but is invoked during jQuery's cleanup on removal to detach event handlers.
     */
    jQuery.event.special.elementRemoved = {
        remove: function(o){
            if(o.handler===dummy && !isUntracking){
                $(this).trigger('removed');
            }
        }
    };
    
    /**
     * Starts removal tracking on an element
     */
    jQuery.fn.trackRemoval = function(){
        this.bind('elementRemoved', dummy);
    };
    
    /**
     * Stops removal tracking on an element
     */
    jQuery.fn.untrackRemoval = function(){
        isUntracking = true;
        this.unbind('elementRemoved', dummy);
        isUntracking = false;
    };
})();

// Track removal of test elements
jQuery('#testParent, #testChild, #testUntrack').trackRemoval();
// Bind some handlers to the bubbling “removed” event
jQuery('ul, #testParent, #testChild, #testUntrack').bind('removed', function(e){
    console.log('About to be detached', e.target, 'caught at', this);
});
// Uncomment to disable tracking if desired
jQuery('#testUntrack').untrackRemoval();

// Remove the parent to trigger handler for child and parent
jQuery('#testParent').remove();
// Remove other element that does not trigger handler
jQuery('#testUntrack').remove();