Hi Tin,

There is a potential for memory leaks via event listeners due to
cyclical references between DOM and JS. To avoid this, GWT manages the
event listeners via the Widget lifecycle. When the widget is attached
to the DOM (i.e. it or it's ancestor is attached to a RootPanel) the
widget's event listener is initialized. When the widget is detached
(or the page is unloaded) the event listener is cleaned up. You can
see the code in Widget.onAttach() and Widget.onDetach().

I'd say it is erroneous to use Widget outside of the normal Widget
containment hierarchy. Instead, we can set an event listener directly:

DOM.setEventListener(buttonElement, new EventListener()
{
  // you will only get the events you sink
  void onBrowserEvent(Event event)
  {
    // references in this method can result in a memory leak
    Window.alert("GWT-hacky-clicked!");
  }
});

// connect the foreign element to the GWT event dispatcher
DOM.sinkEvents(buttonElement, Event.ONCLICK);

Also consider adding a Window CloseHandler to prevent the memory leak.
Window.addCloseHandler(new CloseHandler<Window>() {
  public void onClose(CloseEvent<Window> event)
  {
    DOM.setEventListener(buttonElement, null);
  }
});

You can also look at HandlerManager and DomEvent.fireNativeEvent() to
see how to translate Event into a ClickEvent, but IMO that is
overkill.

-= Mat

On Thu, Jul 16, 2009 at 4:27 PM, tin<[email protected]> wrote:
> I am writing a GWT app that involves interacting with an external
> document in an iframe. As a proof of concept, I am trying to attach a
> click handler to a button.
>
> The following works in javascript
>
> var iframe = document.getElementById("rawJSIFrame");
> var doc = iframe.contentDocument;
> var body = doc.body;
> var button = doc.getElementsByTagName("input").namedItem("submit");
> button.onclick = function() {
>    alert("Clicked!");
> };
>
> Trying to do the equivalent in GWT, I did the following:
>
> public void addClickHandlerToSubmitButton(String buttonElementName,
> ClickHandler clickHandler) {
>    IFrameElement iframe = IFrameElement.as(frame.getElement());
>    Document frameDocument = getIFrameDocument(iframe);
>    if (frameDocument != null) {
>        Element buttonElement = finder(frameDocument).tag("input").name
> (buttonElementName).findOne();
>        ElementWrapper wrapper = new ElementWrapper(buttonElement);
>        HandlerRegistration handlerRegistration =
> wrapper.addClickHandler(clickHandler);
>    }
> }
>
> private native Document getIFrameDocument(IFrameElement iframe)/*-{
>        return iframe.contentDocument;
> }-*/;
>
>
> The following is the ElementWrapper class:
>
> public class ElementWrapper extends Widget implements HasClickHandlers
> {
>
>    public ElementWrapper(Element theElement) {
>        setElement(theElement);
>    }
>
>    public HandlerRegistration addClickHandler(ClickHandler handler) {
>        return addDomHandler(handler, ClickEvent.getType());
>    }
>
>
> }
>
> The code to find the button works fine but the actual click event
> handler is not getting invoked. Has anybody had a similar issue
> before, and how did you resolve it?

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Google Web Toolkit" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/Google-Web-Toolkit?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to