skip to main | skip to sidebar

Tuesday, May 11, 2010

Auto Scrolling Java Script Component

Well after a long break, here I am, back with a component which might be useful for web developers/designers. In this post I’ll try to explain Auto Scrolling Java script component. You might think Auto Scrolling is very old topic and you’ll find many examples of this kind. Even I was thinking the same couple of months ago. I was supposed to work on something similar to this, I thought I can use some existing components with out putting effort to write my own. But ended up writing my own Auto Scrolling component. Reason – Those examples I found did not fit my requirement and are really complicated for a common developer to understand and plugin to existing code. This component is small, simple and can be plugged in to any piece of code [at least my perception] with out any effort. All the source code is free for every body to use [this is also one of the constraint I wrote my own], download it using the links provided a the end of this article. Why wait, lets get on with it.
This component is coded to work with tabular information. This doesn’t mean that you can not use it for other data, with minor changes you can use this component to work with any kind of data. Lets start with the code.
To use this component on tabular data the data has to be in the following format. We need to have one outer table which will have column headers [‘th’ tags] as first row, in the second row, we’ll have one column spanned across all the column, in this column we need to have an inner table with tabular data. Find the template below.
 <table id="col-headers" class="tbl_headers">
  <tr class="colNames">
   <th>Heading-1</th><th>Heading-2</th><th>Heading-3</th><th>Heading-4</th><th>Heading-5</th>
  </tr>
  <tr>
   <td colspan="5">
    <table id="tbl-content" class="tbl_text">
    <tr>
     <td>Column-1</td><td>Column-2</td><td>Column-3</td><td>Column-4</td><td>Column-5</td>
    </tr>
    ...
    </table>
   </td>
  </tr>
 </table>
In the above template 'Heading-1', 'Heading-2', etc are column headings, and ‘Column-1’, ‘Column-2’, etc are data in the table.
 AutoScroller = function (headersTblId, contentTblId) {
  // initial delay in milli seconds
  this.initDelay = 5000;
  // animation delay in milli seconds
  this.delay = 50;
  // initial relative position of the content
  this.position = 0;
  // initialize auto scroll - get container references
  this.el = document.getElementById(headersTblId);
  this.scrollTbl = document.getElementById(contentTblId);
 };
Nothing complex here, its just making the component ready by initializing it. First we’ll set Initial delay – in the above code the initial delay is ‘5000’ milli seconds, which is 5 seconds. This mean when the page/content is loaded, this component waits for 5 seconds before scrolling the text. Then we’ll set the animation delay – in the above code the delay is ‘50’ milli seconds, this value defines how fast/slow you want the scrolling to be. What ever amount of time you give here, component will change the text position by 1px after this amount of time repeatedly. Next value is ‘position’ which is used internally by the code to reference the current position of the text. Next code tries to get DOM references to the headers table and content table. That is all we’ve with initialization of the component, isn’t that simple!, let move on with rest of the code.
 _clearInterval : function () {
  if (!this._interval)
   return;
  clearInterval(this._interval);
  this._interval = null;
 }
This method is used internally to clear animation related flags [time intervals]. When interacting code calls this component multiple times, this component takes care of clearing existing flags and have one scrolling sequence per object. This component uses ‘setTimeout()’ method of Java Script to create the scrolling animation which returns a unique value which we can use to cancel the time out value. In this method we do the same, each time we call setTimeout() method we keep the returned unique value in ‘_interval’ variable. In this method we’ll check if this variable has a value, if it has then call ‘clearInterval()’ to cancel the time out which has been set previously.
 _resetPosition : function () {
  // reset content position
  this.position = 0;
  this.scrollTbl.style.top = "0px";
 }
This method will reset the content’s position to default, it resets the variable ‘position’ to ‘0’ and resets the position by updating style attribute ‘top’ to ‘0px’.
 stop : function () {
  this._clearInterval();
  // reset content position to normal
  this._resetPosition();
 }
This method can be used to stop the scrolling. If you’ve other scripts in your page interacting with this component you can use this method to stop scrolling. First we’ll clear the time outs set previously by calling ‘_clearInterval()’ method and reset the content position to default by calling the ‘_resetPosition()’ method.
 resetColWidth : function () {
  // if no text to re-align - return
  if (!this.el || !this.scrollTbl)
   return false;

  // get table content height
  this.tblHeight = this.scrollTbl.offsetHeight;

  var th = this.el.rows[0].cells;
  var td = this.scrollTbl.rows[0].cells;
  // reset widths for each column header
  for (var i=0;i<td.length;i++) {
   th[i].style.width = td[i].offsetWidth + "px";
  }
  return true;
 } 
‘resetColWidth()’ method is one of the important methods, it resets the width of the header column widths. The need – as we use two different tables for column headings and tabular content, the columns of both tables might not be aligned properly. We need to have some work around to make the columns of both the tables to be aligned properly. This method is for exactly the same purpose. It loops through the columns of the content table and gets the width for each column and sets this width to the same column in the header table. Say if you have a column named ‘column1’ it gets the width of this column text and sets that width to the ‘column1’ width in the heading table. I used ‘offsetWidth’ attribute to get the width and ‘style.width’ attribute to set the width. Bold text in the above code sets the width of column headers.
 getWindowHeight : function () {
  if( typeof( window.innerWidth ) == 'number' ) {
   //Non-IE
   return window.innerHeight;
  }
  if( document.documentElement && ( document.documentElement.clientWidth 
     || document.documentElement.clientHeight ) ) {
   //IE 6+ in 'standards compliant mode'
   return document.documentElement.clientHeight;
  }
  if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
   //IE 4 compatible
   return document.body.clientHeight;
  }
 }
This method returns the current browser window height, this is the standard way/code to get the window height using Java Script. This height will be used a deciding factor whether to scroll the content or not. If the content doesn’t span more than the current height of the window, we wont scroll the content. I thought that its logical to scroll the text only when the content spans more than the window height.
 
 initScroll : function () {
  // clear existing time-outs
  this._clearInterval();
  // reset column widths
  if (!this.resetColWidth())
   return;
  // reset content position
  this._resetPosition();
  this.winHeight = this.getWindowHeight();
  // if scrolling is needed
  if (this.tblHeight > this.winHeight) {
   // start scrolling
   var obj = this;
   this._interval = setTimeout(function () { obj._scroll(); }, this.initDelay);
  }
 }
‘initScroll()’ method initializes the scrolling. First it clears any existing time outs by calling ‘_clearInterval()’, which ensures to have one process of scrolling even when this method gets called multiple times on the same object. Then it tries to re-align the column widths by calling the ‘resetColWidth()’, this method returns false if it couldn’t find references to headers table and content table. Then it calls ‘_resetPosition()’ to reset the the position of the content to default. Then it gets the window height by calling ‘getWindowHeight()’ and checks whether scrolling is needed, if needed it schedules the scroll after initial delay using ‘setTimeout()’ and calling ‘_scroll()’ method in it. ‘_scroll()’ method changes the position of the text by ‘1px’ each time and schedules a call to itself after the configured ‘delay’ using setTimeout(). Code block of ‘_scroll()’ method is given below.
 _scroll : function () {
  // start at bottom after completing one cycle of scrolling
  if (this.position <= (0-this.tblHeight))
   this.position = this.winHeight;
  this.position = this.position - 1;
  this.scrollTbl.style.top = this.position + "px";
  // recursive call periodically
  var obj = this;
  this._interval = setTimeout(function () { obj._scroll(); }, this.delay);
 }
That is all you’ve in this scrolling component. You need to know few more things – basic styles needed for this component. Those simple styles are given below
 <style type="text/css">
  table {
   width: 100%;
   text-align: center;
  }
  .tbl_headers { overflow: hidden; text-align: center; }
  .colnames { background-color: #ccc; }
  .colnames th { padding: 1em; }
  .tbl_text { position: relative; z-index: -1; }
 </style>
Above styles are for the container table, text table and headers. Three important styles classes are 'tbl_headers', 'colNames', and 'tbl_text'. 'tbl_headers' has styles specified for outer table, 'tbl_text' has styles for the inner table which has text to be scrolled, and 'colNames' has styles for column headers. These are very simple styles like back ground color, overflow property, position, and z-index.
Java Script source code and an example HTML page using the above component is available here.

1 comment:

jamie said...

They're not so complicated after all. thanks.

- Managed hosting services

Post a Comment