views:

121

answers:

1

I am programmatically updating the DOM on a WebKit webview via DOMElement objects - for complex UI, there is usually a javascript component to any element that I add. This begs the need to be notified when the updates complete -- is there any such event? I know regular divs dont fire an onload or onready event, correct? The other assumption I had, which may be totally wrong, is that DOMElement updates aren't synchronous, so I can't do something like this and be confident it will meet with the label actually in the DOM:

DOMElement *displayNameLabel = [document createElement:@"div"];
[displayNameLabel setAttribute:@"class" value:@"user-display-name"];
[displayNameLabel setTextContent:currentAvatar.avatarData.displayName];
[[document getElementById:@"user-card-content"] appendChild:displayNameLabel];
id win = [webView windowScriptObject];
[win evaluateWebScript:@"javascriptInstantiateLabel()"];

Is this true?

I am using jquery within the body of the html already, so I don't mind subscribing to a particular classes set of events via "live." I thought I might be able to do something like:

$(".some-class-to-be-added-later").live( "ready", function(){
    // Instantiate some fantastic javascript here for .some-class
});

but have experienced no joy so far. Is there any way on either side (objective-c since I don't programmatically firing javascript post load, or javascript) to be notified when the element is in the DOM?

Thanks, Josh

Edit: Based on Anurag's answer, here's the code I came up with (works):

    function onButtonPanelChange() {
        console.log( "Button panel subtree modified", 7 );
        $(".panel-button").each( function(){
            console.log( "Button found " + $(this).attr( "class" ), 7 );
            if( !$(this).hasClass( "processed" ) ){ 
                $("#bottom-button-panel").unbind( "DOMSubtreeModified" );
                if( $(this).hasClass( "chat" ) ){
                    console.log( "Found chat button, instantiating", 7);
                    var chat_button = new Button( $(this), chat_button_def );
                    $(this).addClass( "processed" );
                }
                else if( $(this).hasClass( "get" ) ){
                    var chat_button = new Button( $(this), get_button_def );
                    $(this).addClass( "processed" );
                }
                $("#bottom-button-panel").bind( "DOMSubtreeModified", onButtonPanelChange );
                console.log( "Done with button change, rebinding", 7 );
            }
        });
    }
    $(document).ready( function(){
        $("#bottom-button-panel").bind( "DOMSubtreeModified", onButtonPanelChange);
    });

Note that you hella need to unbind the event, since each subsequent change fires another event, and another, and another.

+1  A: 

See a similar question that was asked an hour ago - http://stackoverflow.com/questions/2844565/is-there-a-jquery-dom-change-listener

To listen to changes on an element, use something like:

$("#someDiv").bind("DOMSubtreeModified", function() {
    alert("tree changed");
});

I haven't scripted the DOM through Objective-C, so don't know if there's a way to subscribe to DOM events with the Objective-C wrappers.

The DOMSubtreeModified modified event works on the iPhone. Just tested with this example.

Anurag
well indeed. this is fantastic -- I'll try it out.
Josh