Page Resize

We venture into the fully javascript coded front end wherein we will use Ajax to make calls to the API that will return data stored in a database. When we look at the DOM and the parent child relationship that branches up to the “document” within the “window” of the browser, we see that a parent can dictate the substance of a child in the parent/child relationship.

Because of this, and because the parent objects of the browser are the “document” and “window” we must take into consideration the redrawing of children elements on various events triggered by the user via the browser such as resizing the window or refreshing the document part of the DOM. This can happen when triggering “window.location” and “window.location.hash” events as well as the drag and drop of elements within the “document”.

The document and window have a unique problem on the resizing of the browser in that the events fired continue to fire until the resizing by the user has stopped. This can cause a problem in drawing elements over the top of themselves effectively doubling them which then causing problems because there is more than one type of a specific object id. Which of the two objects are you calling? The index will define what lies in front and what lies behind and the elements to the foreground will be acted on first. This leaves second copy elements behind making the user think nothing has been done, when in fact they acted on the first layer of elements.

This can become a massive headache if you are working with the DOM to display a document modelling concept that needs to be redrawn. The DOM will redraw a parent and its siblings no matter how many levels down the tree of children is formed. This means that you can trigger a resize of the parent and all its children and their children will be included in the redraw. The problem with the resize event is that it is continually triggered until the user stops resizing the window and the mouse action ceases. This can cause a redraw to happen fast and continuously, redrawing your elements multiple times on top of each other.

To deal with this. First lets look at what a resize event is and how it is defined in the document. We use a Page::construct to initiate the loading of a Page and all its objects maintained in the Page Parent relationship.

function onresizer(){
     Page.onresize(); 
} 

In our configuration file we have defined the resizer function. It is here that we can check the source “document” and make sure we fire the correct onResize function.

function onresizer(){
  if (window.location.pathname === '/map/editor.html'){ Editor.onresize(); }
  else if (window.location.pathname === '/map/manager.html'){ Manager.onresize(); }
  else { Page.onresize(); }
}

By doing this we can ensure that the current loaded environment triggers its own onResize event. We will investigate the Page model shortly. The Page model allows you to trigger the redrawing of elements on command, this allows the developer to define specificss of an element that are redrawn when the user resizes the browser or triggers a “window” event.

if(window.addEventListener){
  window.addEventListener("resize", onresizer, false);
  window.addEventListener("orientationchange", onresizer, false);
}
else if (window.attachEvent){
  window.attachEvent("onresize", onresizer);
  window.attachEvent("orientationchange", onresizer);
}
else if (window.onresize){
  window.onresize = onresizer;
  window.onorientationchange = onresizer;
}

As we can see by the eventHandler code, we traverse through the “window” to look for a handler to attach to, this is probably not so necassary today with browsers tending to conform to HTML5 model pretty strictly, although in some cases the fallover is required to attach the event Handler to the handle.

We can see that the event Handler calls the onresizer function we defined in the config root which in turn defines the current document and ensures the current documents event handler is triggered. Without this the resize function would not work.

In the example below, we created a Page object which contains a bunch of functions that can be called through the Page object. We have trimmed this down to demonstrate what we are doing. You can see below that Page.init function triggers the page initialisation which in turn triggers the initilisation of child objects that are then attached to the pages elements object. When a resize is triggered by an eventhandler that is attached to the windows document, we have used a time out function or delay before triggering the pages changes.

var Page = {

  _elements:{},

  init: function() {  
    Ajax.init();
    Display.init();
  },

  onresizer: function(){
	clearTimeout(Page._timer);
	Page._timer = setTimeout(function() {
		Page.onresize();	
	}, 350);
  },

  onresize: function(){
	TabPanel.redraw();
	Display.redraw();
	Zoom.redraw();
  },
  end: true
}

Some of you might see very clearly by the functions text what is going on here. When the document is resized by the user this triggers the onresizer event which we have attached the Page.onresize function to. Because the user dragging or changing the documents window size continually triggers the event we cause a delay so that the user has enough time to release the mouses grasp on the windows edge and stops the document resizing from triggering. When this occurs a time out is used to trigger the Pages true onresize function that we linked to in the resizer function.

Because this event is fired continuously until the user stops resizing the window, it will cause a redraw to continually happen which effectively floods the screen with elements. This can crash the browser if too many elements are drawn in a short period of time. Essentially we only want this event to trigger on the stop of a resize, and there is no event handler that tells the DOM the user has stopped resizing. This is why we delay the actual redraw through the resize events setTimeout function which in turn triggers the Page.onresize event which carries out what the developer has defined needs to be redrawn.

To put this in short, a user grabs the window edge, resizes the browser, the onresizer event is continuously triggered. This event deletes and resets a timeout before the actual onresize event of the page is triggered. When the user stops resizing, the delay of 350ms occurs and then the Page.onresize event is finally triggered.

When the Page.onresize event is finally triggered we can see that some of our element objects are then redrawn by the Page event. Some of you may be new to laying your code out in objects from the start of your Page load, however, as we move forward you will see how this becomes important when laying those elements out on the page is concerned.

mycoa.com.au/map/map.html

If we look at our WORD MAP project, we can see that on the display object that is loaded by the Page.init function the resize triggers the redraw of the DOM Elements displaying the word orbits and zoom controls. Without the onresizer time delay the triggered redraw continually draws the circles until many overlay each other, the user would not notice because they are being drawn at specific screen co-ordinates, effectively layers on top of each other. From a developers point of view this is a bad scenario because you are now unable to call a single object because its been replicated many times and instead of one, there are many.

In future lessons we will investigate this Page object further, it technically becomes the Parent object of all your elements created in the document space. As a quick example.. on the display object shown above you can see the Zoom Control elements, the resize triggers event Handlers that manipulate the DOM elements sizes. and locations on screen.

redraw: function(){
    x = DOM.getX(Page._elements.mindmapdisplay);
    y = DOM.getY(Page._elements.mindmapdisplay);

    Zoom.showZoomAt(x+20,y+20);     
},

Our Page.onresize event triggers the Zoom.redraw event which defines the location and often the size of an element and draws it to the screen, we then use some DOM handlers to move the object to a specific x and y co-ordinate after it has been drawn. In the case of the Zoom Control you will notice that it is always drawn twenty pixels from the left and again from the top. This ensures that every time the page is resized or redrawn the element is placed in the left top corner of the display element regardless of the size of the display element.

In our next lesson, we will explore the onload event handler and how we deal with initializing the start of the site from first load. This is an extension to what we have laid out here by attaching the onresizer event handler to the documents window except we will attach an onload event that configures the Page element and manages the handling of appended elements to this Page Object.

Hopefully this is explained well enough. Im not a teacher, I am a programmer. Through this blog we intend to improve our programming, our code and our implementation of that code, and in doing so, hopefully manage to teach some upcoming programmers some neat coding tricks to give you a better comprehension of a corporate level web site.

« »

1 comment

  1. And yes, i have noticed that there are some issues in this word press theme. This includes some unfinished work like with this comments entry field. We havent forgotten. There is a rebuild of that entire theme planned and possibly a release of it on the WordPress Store.

Leave a comment

Your email address will not be published. Required fields are marked *