views:

1807

answers:

2

I'm trying to get a child JavaScript application to update it's parent document.

In essence, this is a very simple problem:

  • a JavaScript program opens an iframe in it's own document.
  • another JavaScript program is loaded into the iframe.
  • the second program needs to change the fragment (anchor) in the original page.
  • the first program, then "goes" to the new fragment (the document position is updated, but the document is not refreshed).

In an endless number of web pages there are descriptions of how to do this, using tricks like:

window.parent.location.hash = "#" + string

But when I do this in IE, the parent appears to be refreshing itself. I think the page is reloading.

Just to make this a bit trickier:

  • I need solutions for all browsers (or at very least IE and Firefox).
  • Both JavaScript programs are actually GWT web apps (so I can tie specific code to different browser versions).
  • If necessary I can do weird things to get around security, the parent and child will always be known to each other. The child is always called by the parent.

I've tried a bunch of other tricks listed on various web pages, but so far nothing seems stable and simple enough to actually be deployed.

+1  A: 

Use element.scrollIntoView or scrollTo depending on your browser.

geowa4
It's interesting, but I think GWT creates the anchors on the fly, so I have no element until I've actually gone to that fragment.
Paul W Homer
Or at least I have no way of referencing the element, until I've gone to that fragment.
Paul W Homer
`"#" + string` tells me that the string is the id, if you have that, you can get the element
geowa4
am i wrong? if so, what is `string`?
geowa4
The string I'm using contains a 'token' that GWT sends back to me thru its history mech, and some arguments. Most of the time I don't think a matching element actually exists, until the user goes to that anchor (but I'm not entirely sure, it is buried in GWT).
Paul W Homer
Right now, in the string I use a path-like navigation for the menus (separated by :), and a set of URL-argument-like arguments. All of this is very legal in the fragments (which allows a huge range of characters).
Paul W Homer
well, adding "#someid" to the url requires the element to exist with that id already. otherwise it won't do anything.
geowa4
I'm searching, but I think what happens is that somewhere GWT is listening to the document location variable, then when it changes it calls onHistoryChanged in the app, which allows the app to redraw. This behavior may also be why my attempts to just update the fragment cause reloads. The problem is that it seems deeply buried in GWT.
Paul W Homer
A: 

I found the following JavaScript in my app (generated by GWT):

function $initUrlCheckTimer(this$static){
  var historyImplRef = this$static;
  var urlChecker = function(){
    $wnd.setTimeout(urlChecker, 250);
    var hash = getLocationHash();
    if (hash.length > 0) {
      var token = '';
      try {
        token = historyImplRef.decodeFragment(hash.substring(1));
      }
       catch (e) {
        $wnd.location.reload();
      }
      var historyToken = ($clinit_75() , $wnd.__gwt_historyToken || '');
      if (historyToken && token != historyToken) {
        $wnd.location.reload();
      }
    }
  }
  ;
  urlChecker();
}

I did notice that the top level document in GWT calls down to the application one (the generated code starts with assigning parent to $wnd, where $wnd.location is my actual URL).

What I'm thinking (and I could be wrong about this) is that the GWT history mech involves watching __gwt_historyToken, until it changes, then updates the app. If the parent location changes, "something else" seems to be forcing a reload as well. I can't just change the document location, without somehow integrating it with this GWT code.

Paul W Homer