views:

62

answers:

3

I'm dealing with a ball-of-mudd project that uses frames & iframes to create a "customizable" interface (like people did in 2002).

The application runs from within a hta and kind of emulates a real WPF style app. I need to capture keys so I can selectively change/refresh some of the subframes.

What I'm trying to do is, if there was a sub-sub frame called desktop and that had some frames in it how would I capture an event, safely, across all frames; and refresh a frames subframes?

Any help appreciated; I accept no responsibility for nausia caused by repeating the last paragraph too many times. :)

A: 

I don't know anything about HTA, but the question is marked as javascript / jquery / iframe, so i'll guess it isn't a problem...

You can use an object in window.top to manage your events in a centralized place.

In your main window, you use something like:

    var getTopObject = function() {
        return window.top.topObject;
    }

    var TopClass = function () {

        this.processClick = function (frame) {
            //do something...
            alert('click in ' + frame.document.location.toString());

            var msj = frame.document.getElementById("msj");
            msj.innerHTML = "change!";
        };
    }

    window.top.topObject = new TopClass();

And then, on every iframe, you put:

window.onclick = function () { getTopObject().processClick(window); };

That way you get notified of the click event. Also note that inside the 'processClick' function in the example you can access the iframe document.

Of course, you can do this a lot more complex, but that's the basic idea. You will have to deal with different events in your case.

Hope this helps, and sorry for my english!

Pato
I'm attempting to do it by rolling through the dom tree, as the 'desktop' has a variable number of iframes. Painful doesnt cover it
Chris M
I don't understand what is the problem... Can you be more specific?
Pato
There are frames within frames (upto 7 deep in places)
Chris M
A: 

Working; digs through the frames in a loop using a function calling itself; I limited it to 8 rather as I know thats the deepest it will get. You can always change that yourself.

var XXX_util_keyboard = function()
{

 //"private" variables:
 var objTopWindow = top.window.frames,
  arrFrames = [],
  MaxDepth = 8;

 //"private" methods:
 var AddToArray = function(obj){
  if(typeof obj.document != "undefined") {
   arrFrames.push(obj);
   return true;
  }
  return false;
 };

 var DeleteFromArray = function(obj){
  if(typeof obj != "undefined") {
   arrFrames.splice(arrFrames.indexOf(obj), 1);
   return true;
  }
  return false;
 };

 var FrameLoop = function(objFrames){
  if(MaxDepth > 0){
   if(objFrames !== null)
   {
    for(var k = 0; k < objFrames.frames.length; k++)
    {
     var tmp = objFrames.frames[k];
       AddToArray( tmp );
       FrameLoop( tmp );
    }
    this.MaxDepth--;
   }
  }
 };

 var AttachEvent = function(key, fn) {

  for(var i = 0; i < arrFrames.length; i++){
   arrFrames[i].document.onkeypress =  function(e) {
             var evt = e || window.event,
              charCode;
              if(evt === null){ evt = this.parentWindow.event; /*IE doesnt capture scope correctly*/ }
              charCode = evt.keyCode || evt.which;
              alert(charCode);

              evt.cancelBubble = true;
              if (evt.stopPropagation){ evt.stopPropagation();}             
            };
  }

 };

 return {

  init: function()
  {
   AddToArray(this.getTopWindow()[0]);
   FrameLoop(this.getTopWindow()[0]);
  },

  getFrames: function()
  {
   if(arrFrames.length < 1){ FrameLoop(objTopWindow[0]); }
   return arrFrames;
  },

  getTopWindow: function()
  {
   return objTopWindow === undefined ? window.frames : objTopWindow.window.frames;
  },

  attachEvent: function()
  {
   if(arrFrames.length < 1){ FrameLoop(objTopWindow[0]); }
   AttachEvent();
  }

 };

}();
Chris M
+1  A: 

Answering to get the formatting

arrFrames[i].document.onkeypress = function(){
  var evtobj = window.event ? event : e;
  evtobj.cancelBubble = true;
  if (evtobj.stopPropagation){ evtobj.stopPropagation();}
  top.console.log(evtobj.type+' - '+(evtobj.which?evtobj.which:evtobj.keyCode));
};
mplungjan
Ta; id just realised the mistake in the version i was faffing with after looking at another post (http://stackoverflow.com/questions/1629926/element-onkeydown-keycode-javascript) temporary brain damage
Chris M