Search code examples
javascriptjqueryeventsdomtiddlywiki

What event fires when elements are added or removed in the document?


I am making a sort of tabbed interface for a Tiddlywiki, and I am wondering how to get this code to fire every time a tiddler is opened or closed. Tiddlywiki is an HTML notebook type of thing that runs in the browser, and a tiddler is a div in #tiddlerDisplay. There can be, and usually are, more than one in it at a time.

The divs I want to list are contained in #tiddlerDisplay, and the list itself is jQuery("#mainMenu > #singleTiddlerList").

config.macros.singleTiddler.update = function(){
    jQuery("#mainMenu > #singleTiddlerList").empty();
    jQuery("#tiddlerDisplay > div").each(function(i,e){
        jQuery("#mainMenu > #singleTiddlerList").append(jQuery(
            createTiddlyButton(document.createElement("li"),jQuery(e).attr("tiddler"),"",config.macros.singleTiddler.clickHandler)
        ).parent());
    });
};

Update: I can't just add a custom event, unless I can do it from outside the current code (such as something that fires on document load).


Solution

  • One way is jQuery("#tiddlerDisplay").bind("DOMSubtreeModified", config.macros.singleTiddler.update);, however i think this only works in Chrome (maybe Opera or Safari, not sure), and also appears to be deprecated. Firefox has a duo of events to accomplish the same thing, but i think these are also deprecated.

    Another way I found after reading this article and exploring the TiddlyWiki source code is this:

    (function( $, oldRem ){
        Story.prototype.displayTiddler = function(){
            var resp = oldRem.apply( this, arguments );
            $("#tiddlerDisplay").trigger("displayTiddler");
            return(resp);
        };
    })( jQuery, Story.prototype.displayTiddler );
    (function( $, oldRem ){
        Story.prototype.closeTiddler = function(){
            var resp = oldRem.apply( this, arguments );
            $("#tiddlerDisplay").trigger("closeTiddler");
            return(resp);
        };
    })( jQuery, Story.prototype.closeTiddler );
    jQuery("#tiddlerDisplay").bind("displayTiddler", config.macros.singleTiddler.update);
    jQuery("#tiddlerDisplay").bind("closeTiddler", config.macros.singleTiddler.update);
    

    Notice that the event fires after the tiddler opens or closes. Also, as the article states, jQuery can be bugged in the same way, but I don't know about the native DOM methods, and I kind of doubt it. There's supposed to be an event for it, but regardless, everyone should totally drop them and use jQuery!