You are on page 1of 15

JavaScript Guide 15/02/24, 12:09 PM

LabVantage JavaScript Guide

Content

Introduction Performance
Writing JavaScript Preventing Memory Leaks
General Guidelines Useful Utilities
Script Files
Application Resources
The LabVantage API
Objects & Classes
Example
Useful API Functions

Introduction

The LabVantage JavaScript Global API provides developers with enhanced client-side functionality. This document outlines
standards for JavaScript authoring, details performance considerations, and describes LabVantage JavaScript Global API
functionality.

Writing JavaScript

General Guidelines
Follow these guidelines when writing JavaScript for LabVantage:

1. Script Files
Try to use script files rather than writing the script within the JSP or HTML. See Script Files for details.

2. Naming Conventions
Use these JavaScript naming conventions (refer to http://articles.techrepublic.com.com/5100-22-5109485.html):
• Function names should use Camel Notation, i.e., begin with a lowercase letter, and the first letter of each
subsequent new word is upper case with all other letters lower case).
• Class names should begin with a capital letter, and the first letter of each subsequent new word should be
capitalized with all other letters lower case.
• Variable names should use Camel Notation.
• Variable names should use Hungarian Notation and indicate their data type with a consistent prefix (l - boolean; n
- floating point; i - integer; o - object; s - string).
• Variable and Function names should demonstrate their purpose.

3. Use JavaScript Object Orientation


Write your new scripts within JavaScript objects. See Objects & Classes for details.

4. Keep Quotes Consistent


Generally, JavaScript code is written using single quotes (in contrast with double quotes for HTML and Java). The
benefit with using single quotes over double quotes is that you can type JavaScript into Java code and into HTML tags
without having to escape every double quote. Whichever quote type you use, make sure it is consistent for your entire
script file. This will minimize confusion and bugs.

5. Do Not Over Comment


It is good practice to comment areas of code to help other developers (and you) identify what the variable and
algorithm is doing. However, you should limit your comments to an absolute minimum. It has been observed that
developers often place JavaDoc-type descriptions at the beginning of methods, properties and JS files. The problem
with this is it significantly increases the bandwidth required to download the script file, and slows the interpreter speed
as it processes the larger file. If you have written a complicated file that requires detailed comments, consider writing
a simple API document that describes the script, then pointing to this in your JS file.

file:///Users/aditya_saharay/Desktop/Lab%20Informatics/COTS%20Pro…08.6/Content/javascript/javascript_guide.htm#ApplicationResources Page 1 of 15
JavaScript Guide 15/02/24, 12:09 PM

6. Be Strict With Type


JavaScript is a type-less language, and variables can be converted from one type to the other without any casting.
However, using one variable for multiple types can cause confusion and introduce bugs. Therefore, make sure you
declare a variable that is used for just one type. If you then convert the type of the variable, create a new variable to
hold this new type. You should use the Hungarian Notation naming convention outlined above to assist in the type
management of your code.

7. Write For Performance


JavaScript is an interpreted language and unlike Java (which uses a complier), it is not forgiving of poorly written code.
Therefore, you should obey the performance tips that are in the Performance section of this document.

8. Parentheses
Take advantage of parentheses to ensure that a mathematical result is calculated as expected. For example, are x and
y equal:
var x = 2 * 3 + 2 / 2 + 2
var y = (((2 * 3) + 2)/(2 + 2))

9. Coding style
Use a consistent style when writing JavaScript. This makes it easier to understand from other developers. The coding
style to use is the same as Java code, with curly brackets at the end of the line, and a space after the parentheses:
function MyClass( ){
this.myFunction = new function( sMyString, iMyInt ){
for ( var iIndex = 0; iIndex < 10; iIndex++ ){
alert( iIndex );
}
}
}
10. Semicolons
JavaScript can be written with or without semicolons at the end of a statement. To be consistent throughout
LabVantage, all new JavaScript code should be written with a semicolon at the end of a line or statement.

Script Files
JavaScript in LabVantage has evolved from a few lines of code that changes the color of a button, to thousands of lines of
code that control all aspects of the application. JavaScript development habits must evolve with the language.
For example, placing code directly into a JSP or HTML page rather than into a separate script file causes a big performance
drain, as this code has to be downloaded to the client every time the page loads.
Therefore, new code (or any code encountered during a JSP change) should be placed into a related JS file. This JS file should
then be placed in the "scripts" folder for the context of your item. Or, create an Application Resource. For example, if you
write a new Page Type called "SuperPageType" with a JS class of SuperPageType, all JavaScript code for this page type should
be placed in a "superpagetype.js" (same name but in lower case) file in the "scripts" folder associated with this Page Type.
Alternatively, if you write an Element called "MyElement", create a script file called "myelement.js", and place it in the scripts
folder for this Element. Here are some examples:

Item Item Name JS Class JS Object JS Filename JS File Location


Name Name

Element ANewElement ANewElement aNewElement anewelement.js WEB-CORE/elements/scripts/

Page PowerList PowerList powerList powerlist.js WEB-CORE/pagetypes/scripts/


Type

Page SampleList SampleList sampleList samplelist.js WEB-CORE/pagetypes/list/scripts/

Utility LV_BioBankList N/A N/A N/A Submit for approval as a new


in Module LV_AnotherBBList Module.

Application Resources
Beginning in LabVantage 8.5, you can store javascript and css resources in a dedicated register within LabVantage. This will
be called an Application Resource.

file:///Users/aditya_saharay/Desktop/Lab%20Informatics/COTS%20Pro…08.6/Content/javascript/javascript_guide.htm#ApplicationResources Page 2 of 15
JavaScript Guide 15/02/24, 12:09 PM

Navigate to System Admin > Web Page Designer > Application Resources
From the list page you can add, edit, copy or delete a resource. Other tasks can be performed through the toolbar on the list
page. Below is an example of adding a resource.

The resource source can be either "url" or "attachment". If the source is defined as "url", the source can be set as a path
within the labvantage.war file, i.e. "WEB-CORE/scripts/json.js". If the source is defined as "attachment" the resource needs to
be provided as an attachment of the application resource. The first attachment of type "Application Resource" will be used. In
the standard configuration only one attachment is allowed for per application resource.
Application resource javascripts are supported by:

Page Types Elements Gizmo Types Policies

Maintenance Form advancedtoolbar Button GUPolicy

Maintenance List

DataEntry

DataEntryByQuery

DataChartPage

Prompt

Application resource CSS are supported by the GUIPolicy


In the element/pagetype/policy configuration AppResource can now be selected as type for the include. That will enable the
"Application Resource" input allowing the selection of an item from the LV_AppResource register. The lookup will filter
resources to only list css or javascript depending on context.

file:///Users/aditya_saharay/Desktop/Lab%20Informatics/COTS%20Pro…08.6/Content/javascript/javascript_guide.htm#ApplicationResources Page 3 of 15
JavaScript Guide 15/02/24, 12:09 PM

Minification
Beginning in LabVantage 8.6, you can use LabVantage to minify your JavaScript or CSS. Minification refers to the process of
removing unnecessary or redundant data without affecting how the resource is processed by the browser. Examples include
code comments, formatting, unused code, shorter variable and function names, and so on. Minification dramatically improves
site speed and accessibility, directly translating into a better user experience. LabVantage now includes the YUI Compressor as
an option for you to minify JavaScript and CSS resources.
Minification of the attached resource is initiated manually on the maintenance page by clicking the Minify button. Minification
of the attached file will be attempted.
Prior to Minification

After Minification (An Example)

file:///Users/aditya_saharay/Desktop/Lab%20Informatics/COTS%20Pro…08.6/Content/javascript/javascript_guide.htm#ApplicationResources Page 4 of 15
JavaScript Guide 15/02/24, 12:09 PM

Minification will fail with a warning if no Application Resource attachment is found or if there are errors when running the
minification. Errors are often due to incompatible javascript content.
Minification will succeed, but display a warning if warnings are issued during minification.
After successful minification, the minified JS or CSS will be stored as a second attachment to the application resource with
class "Minified Application Resource". By default, the minified version of the file will be provided by configuration includes,
when the minified attachment exists. This can be overridden by setting the GUIPolicy property "Use Full Un-minified Includes"
to Yes. This is an Advanced property. You can also choose to use the un-minified version of a specific application resource

file:///Users/aditya_saharay/Desktop/Lab%20Informatics/COTS%20Pro…08.6/Content/javascript/javascript_guide.htm#ApplicationResources Page 5 of 15
JavaScript Guide 15/02/24, 12:09 PM

by setting the checkbox for the resource:

When uploading a new version of the original attachment file, you will first need to delete all previous attachments including
original and minified versions.

The LabVantage API


Begining with R4.7, LabVantage contains a comprehensive and documented JavaScript Global API for public use. Not only
should your new functions and objects use this API wherever possible, but if you write a global feature in JavaScript, the
feature should be placed into this API.

Objects & Classes


When writing JavaScript, use object orientation. This means you create a JS file with several global functions such as
"addAThing" and "removeAThing", then include this into your page. However, if another developer also creates a function
called "addAThing" and includes it into the same page, the two objects will override each other. Imagine a LabVantage
Maintenance page with two different Elements, each created by a different developer.
As you will see with the new API files, we now employ a package-like structure to our client-side script. This has the benefit of
not only separating functionality, but also protects against such clashes.
Therefore, when you create a new script file for an Element, Page Type, or feature, you must first create a new class for this
item using the same name. For example, if you create a new Element called "MyElement", you will have a JS file called
"myelement" with a class called "MyElement" (see Script Files for examples).
To create a class in JavaScript, use the function syntax:
function MyElement(){
// this is a function as a class
}
Then, to instantiate the object, use this syntax:
var myelement = new MyElement();
In any script files you create you should make the object self instantiating by placing the initialization script at the end of the
file:
function MyElement(){
// this is a function as a class
}
if (typeof(myelement) == 'undefined'){
var myelement = new MyElement();
}
Therefore, any class can be called as soon as the file is included into the HTML or JSP. The "typeof()" line makes sure that that
object does not already exist in the current scope. To add a public property (accessible from outside the object using
obectname.property) to the class, use the "this.propertyName" syntax:
function MyElement(){
this.myPublicProperty = 'Hello World';
}
To add a private property (accessible only from functions within the object) to the object, use the "var propertyName" syntax:

function MyElement(){
var myPrivateProperty = 'Hello World Again';

file:///Users/aditya_saharay/Desktop/Lab%20Informatics/COTS%20Pro…08.6/Content/javascript/javascript_guide.htm#ApplicationResources Page 6 of 15
JavaScript Guide 15/02/24, 12:09 PM

}
To declare a public function within the object, use the syntax:
function MyElement(){
this.myPublicFunction = function(){
// function contents
}
}
To declare a private function within the object, use the syntax:
function MyElement(){
function myPrivateFunction(){
// function contents
}
}

Example
This is an example file called "MyElement.js". It is for a new Element called "MyElement". The file should be placed in "WEB-
CORE/elements/scripts/".
function MyElement(){
this.sMyName = 'Steve';
this.sMyEyeColor = 'blue';
var iMyAge = 28;

this.setUser = function( sName, sEyeColor, iAge ){


this.sMyName = sName;
this.sMyEyeColor = 'blue';
iMyAge = iAge;
sayHello( );
}

this.getAge = function( ){
return iMyAge;
}

function sayHello( sName, iAge ){


alert( 'Hello ' + sName + '. You are ' + iAge + '.' );
}
}
if ( typeof(myelement) == 'undefined' ){
var myelement = new MyElement( );
}

The JSP that is part of my element can then call the functions from the file once it has been included.
<script src="WEB-CORE/elements/scripts/MyElement.js"></script>
<script>
myelement.setUser( 'Steve', 'Blue', 28 );
alert( myelement.sMyName );
alert( myelement.sMyEyeColor );
alert( myelement.getAge( ) );
</script>

Useful API Functions


As mentioned above, the JavaScript API provides you with a global set of objects and functions that can do anything from
show a dialog to perform an Ajax request. The API is accessible from any page or iframe that uses one of the LabVantage
Layouts. Although the LabVantage JavaScript Global API document details every object, property and method, here are some
of the methods you should be using rather than coding them yourself:

1. Dialogs
The sapphire.ui.dialog object controls and shows new LabVantage dialogs and popups.
This shows an alert box... use it instead of "alert()":

file:///Users/aditya_saharay/Desktop/Lab%20Informatics/COTS%20Pro…08.6/Content/javascript/javascript_guide.htm#ApplicationResources Page 7 of 15
JavaScript Guide 15/02/24, 12:09 PM

sapphire.ui.dialog.alert( 'hello world' )


This shows a more detailed alert box... use it instead of "alert()", "showModlessDialog" or "showModalDialog":
sapphire.ui.dialog.show( 'My Message', 'Hello' )
This prompts for text entry... use it instead of "prompt()":
sapphire.ui.dialog.prompt( 'My Prompt', 'Please enter' )
This confirms a decision for you... use it instead of "confirm()":
sapphire.ui.dialog.confirm( 'My Confirm', 'Please confirm' )

2. Ajax
The sapphire.ajax object controls the new Ajax API.
This calls a LabVantage Ajax class with the sent properties:
sapphire.ajax.callClass( 'com.labvantage.sapphire.myAjaxClass', myCallbackFunction,
myProps )
This calls a LabVantage Ajax service with the sent properties:
sapphire.ajax.callService( 'com.labvantage.sapphire.myAjaxService',
myCallbackFunction, myProps )
This calls a LabVantage Ajax command with the sent properties:
sapphire.ajax. callCommand( 'com.labvantage.sapphire.myAjaxCommand',
myCallbackFunction, myProps )

3. Connection Information
Using the sapphire.connection object and sapphire.page object, you can get connection details, user information,
and page information.
To get the connection Id of the LabVantage connection:
sapphire.connection.connectionId
To get the database Id of the LabVantage connection:
sapphire.connection.databaseId
To get the user Id of the current LabVantage user:
sapphire.connection.sysUserId
To get the current page name:
sapphire.page.name
4. Maintenance List and Maintenance Form
You can use the sapphire.page.list and sapphire.page.maint objects to perform public functionality on List pages
and Maintenance pages, respectively. Here are a few examples:
To open the Add Maintenance page:
sapphire.page.list.add( sAPage, sTarget )
To get the selected items in the current page or all pages (and return all default columns or the specified
columns):
sapphire.page.getSelected( '', true )
To open the Add Maintenance page:
sapphire.page.maint.add(sAPage, sTarget )
To obtain keyid1 from the Maintenance page:
sapphire.page.maint.getKeyId1 ( )

5. Animations
R4.6 introduced graphical animations on the user interface. These animations can be switched on and off for each user,
or globally for the application. You can use these animations to show and hide any HTML object.
To show an object using a fade in transition:
sapphire.ui.animation.fadeIn( 'myDiv', 10, 20, 0, 100 )
To hide an object using a fade out transition:
sapphire.ui.animation.fadeOut( 'myDiv', 10, 20, 0, 100 )
To show an object using a resize in vertical transition:
sapphire.ui.animation.showObjectVertical ( 'myDiv', 10, 20 )

file:///Users/aditya_saharay/Desktop/Lab%20Informatics/COTS%20Pro…08.6/Content/javascript/javascript_guide.htm#ApplicationResources Page 8 of 15
JavaScript Guide 15/02/24, 12:09 PM

To show an object using a resize in horizontal transition:


sapphire.ui.animation.showObjectHorizontal( 'myDiv', 10, 20 )
To hide an object using a resize out vertical transition:
sapphire.ui.animation.hideObjectVertical( 'myDiv', 10, 20 )
To hide an object using a resize out horizontal transition:
sapphire.ui.animation.hideObjectHorizontal ( 'myDiv', 10, 20 )

6. Drag & Drop and Lines


The API also contains full management for drag & drop, and drawing dynamic lines/links between HTML elements (such
as flow charts). See the LabVantage JavaScript Global API document for more information on sapphire.ui.dragdrop
and sapphire.ui.link.

Performance

Performance is a major factor to consider as client-side functionality grows. JavaScript (unlike Java) is an interpreted
language, and calls its methods and properties through a form of structured referencing. Therefore, code that would normally
perform well in a compiled language can run very slowly in JavaScript. To write more efficient and faster code, these
guidelines should be followed:

1. Cache your scripts


As mentioned earlier, if you type code directly into an HTML page or JSP page then that script content is downloaded to
the client every time the page loads or refreshes. For large script content this can be a huge performance overhead.
Therefore, unless absolutely necessary, all script should be placed in an external JS file and not in the JSP itself. You
should also try and restrict all your JavaScript for one page to one file rather than multiple files. This is due to the fact
that when using multiple JS files a HTTP connection to the server is required for each file, which can reduce
performance.

2. Cache your objects


The nature of JavaScript is to always lookup a reference to an object or property and therefore each time you call
"document.all.length" the JavaScript engine will lookup the "document" object and then the "all" object before obtaining
the "length" property. If this is called repeatedly in a loop or a number of times in a method then noticeable
performance degradation can occur. Therefore by storing the object in a variable and then using the variable we get
better performance:
Bad example:
span style='font-size:9.0pt; font-family:"Courier New"'>alert('The length is: ' +
document.all.length);
while ( true ){
if ( document.all ){
alert(document.all[0]);
}
}
Good example:
var oDocAll = document.all;
alert("The length is: " + oDocAll.length);
while ( true ){
if ( oDocAll ){
alert(oDocAll[0]);
}
}

3. Cache your properties


As with objects, JavaScript will lookup a property using a reference mechanism every time it is accessed. Therefore, it
is also important to cache your properties, especially when used successively in iterations (such as a for loop.
Bad example:
var sMyString = '';
for ( var iIndex = 0; iIndex < saLongArray.length; iIndex ++ ){
sMyString += saLongArray[iIndex];
}
Good example:
var sMyString = '';

file:///Users/aditya_saharay/Desktop/Lab%20Informatics/COTS%20Pro…08.6/Content/javascript/javascript_guide.htm#ApplicationResources Page 9 of 15
JavaScript Guide 15/02/24, 12:09 PM

var iLength = saLongArray.length;


for ( var iIndex = 0; iIndex < iLength; iIndex ++ ){
sMyString += saLongArray[iIndex]
}

4. Use "var"
Always declare the function level variables with the "var" keyword. If you declare a new variable in JavaScript without
the "var" keyword then the variable is given a global scope. This not only could lead to clashes in the code from other
variables with the same name, but also will keep the variable or object active in memory until the page is disposed.
Therefore you must always declare local function variables using the "var" keyword.
Bad example:
function myFunction( ){
sMyString = '';
sMyString += 'Hello';
alert( sMyString );
}
Good example:
function myFunction( ){
var sMyString = '';
sMyString += 'Hello';
alert( sMyString );
}

5. Fragment documents
Use document fragments (rather than using the document object directly) when updating the DOM. When you update
the document structure using "createElement" and "appendChild", the document refreshes its structure at every
update. This can be a large performance drain. To prevent this, you should use the
"document.createDocumentFragment" method to return a workable fragment of the document that can then be
appended to the parent document after you are done with it.
Bad example:
var oEl1 = document.createElement('div');
oEl1.id = 'myDiv';
var oEl2 = document.createElement('span');
oEl2.id = 'mySpan';
var oEl3 = document.createElement('font');
oEl3.innerText = 'Hello';
document.body.appendChild(oEl1);
document.body.appendChild(oEl2);
document.body.appendChild(oEl3);
Good example:
var oDoc = document;
var oEl1 = oDoc.createElement('div');
oEl1.id = 'myDiv';
var oEl2 = oDoc.createElement('span');
oEl2.id = 'mySpan';
var oEl3 = oDoc.createElement('font');
oEl3.innerText = 'Hello';
var oFrag = oDoc.createDocumentFragment();
oFrag.appendChild(oEl1);
oFrag.appendChild(oEl2);
oFrag.appendChild(oEl3);
oDoc.body.appendChild(oFrag);
6. Know the performance hits of methods and properties
A few of the fundamental core objects, properties and functions are quite expensive in terms of memory and processing
power. Two of the largest performance drains are "document.getElementById" and "element.innerHTML".
When using "getElementById" it is important to cache the returned object otherwise the JavaScript engine will look up
the document structure and locate the element each time it is called:
Bad example:
if ( document.getElementById( 'myElement' ) != null ){
if (document.getElementById( 'myElement' ).value != 'Hello'){
alert(document.getElementById( 'myElement' ).value );

file:///Users/aditya_saharay/Desktop/Lab%20Informatics/COTS%20Pro…8.6/Content/javascript/javascript_guide.htm#ApplicationResources Page 10 of 15
JavaScript Guide 15/02/24, 12:09 PM

}
}
Good example:
var oElement = document.getElementById( 'myElement' );
if ( oElement != null ){
var sValue = oElement.value;
if ( sValue != 'Hello' ){
alert( sValue );
}
}
When using "innerHTML" always buffer the HTML content before setting it back, otherwise the JavaScript engine will
rebuild the document structure every time the HTML is updated:
Bad example:
for ( var iIndex = 0; iIndex < iANumber; iIndex++){
oMyElement.innerHTML += '<br>' + iIndex + '</br>';
}
Good example:
var sHtml = '';
for ( var iIndex = 0; iIndex < iANumber; iIndex++){
sHtml += '<br>' + iIndex + '</br>';
}
oMyElement.innerHTML = sHtml;

7. Use Ajax to render large client side structures


If you are dynamically rendering a large amount of client-side HTML (such as loading a list of values depending of
another value), use Ajax to render instead of the JavaScript engine. Even if you obey the performance improvements
above, JavaScript is still slow at manipulating the DOM and creating large amounts of dynamic HTML. A simple Ajax
method that creates an HTML string, followed by a JavaScript callback function that pushes the HTML into the
innerHTML of a containing object, can be significantly faster.

Preventing Memory Leaks

In JavaScript, these two types of memory leaks frequently occur:


Circular References
Circular references are caused by references between DOM objects and JavaScript objects. The IE framework is built on
COM. As such, the DOM and JS engines (and any DOM element) are COM objects with their own garbage collector.
Therefore, references between different COM objects cannot be collected by the memory management routines... even
when the browser is refreshed. Apparently, this is not a bug with IE. Rather, it is a design feature to increase stability.
However, what it means is that unless you clear references on DOM objects to JS objects or other DOM objects, memory
will be wasted. Examples are event handlers on input fields, and properties added to one DIV that point to another DIV.
References:
http://www.barelyfitz.com/screencast/javascript/memory-leak/
http://www.bazon.net/mishoo/articles.epl?art_id=824
http://support.microsoft.com/kb/830555

DOM Leaks
DOM leaks occur when a DOM object is removed from the DOM, but stays in memory. This memory is freed when the
page is refreshed, but can lead to the page quickly becoming unresponsive. Two causes are:
• When you create a DOM object dynamically in a method and return it, the JS engine still maintains a link to that
variable.
• When you use removeChild or removeChildNode, the methods remove the object from the DOM, but do not remove
the object from memory.
References:
http://www.hedgerwow.com/360/dhtml/ie6_memory_leak_fix/
http://ajaxian.com/archives/is-finally-the-answer-to-all-ie6-memory-leak-issues

To see if your application contains memory leaks, you can use the free Process Explorer tool from Microsoft. This tool shows
you memory in use by an application. If you examine the JavaScript application, you will notice that when you use the web
page, the memory will increase. Then, after a refresh, not all memory is released:

file:///Users/aditya_saharay/Desktop/Lab%20Informatics/COTS%20Pro…08.6/Content/javascript/javascript_guide.htm#ApplicationResources Page 11 of 15
JavaScript Guide 15/02/24, 12:09 PM

To prevent such crippling memory leaks, follow these guidelines:

1. Use the sapphire garbage collector


The sapphire.garbage object can dispose of your DOM objects more effectively. When you want to dispose of a DOM
object (or set of DOM objects) use the method:
sapphire.garbage.add( oElement )
This will safely remove your Element from the page and place in a garbage bin object. Then, when the garbage bin
meets its object limit (10 by default), it will call the collection routines to remove the objects from memory. If you are
handling large objects (such as divs with a great deal of content), you can also force the garbage collector to run using:
sapphire.garbage.collect()
This method will also activate the DOM and JS engine collection routines, thus freeing memory. All of our API
functionality now makes use of this feature. Accordingly, use this if you add new functionality that creates dynamic
content on a page.

2. Create DOM objects in a try-finally


When you have a method to create a DOM object and return it, surround the return statement with a try-finally. This
stops the circular references from the DOM object link being kept in memory. Example:
var o = document.createElement('div');
try {
return o;
}
finally {
o = null
}

3. Remove circular references


When you are finished with your DOM object, remove any attributes you have added that are references to other
objects. An example is a DIV element with which you add a link to a JS object or another DIV. The best methodology is
to have a dispose method that accompanies your functionality. The dispose method should create the DOM object, then
call the algorithm to null out any object attributes, then send to the garbage bin.

4. Remove event handlers


As with circular references, any events you attach to a DOM object will keep the DOM object in memory. Therefore, in
the dispose method, use a detachEvent call to remove any events that have been added. Events that are added using
the anonymous technique will not suffer the memory leak issue and do not need to be removed.

5. Dispose any xml schema or extended class names


An XML schema or extended class name is a style class that uses advanced imported XML namespaces and functionality

file:///Users/aditya_saharay/Desktop/Lab%20Informatics/COTS%20Pro…8.6/Content/javascript/javascript_guide.htm#ApplicationResources Page 12 of 15
JavaScript Guide 15/02/24, 12:09 PM

such as "time" or any classes that uses behaviors. These offer linked functionality to other COM objects. Therefore,
when a DOM object is disposed with a class name, the COM object still references it. The best course of action is to add
the removal of any complex class names from the object before you send it to the garbage bin in your disposal method.

Once you are managing memory correctly and the garbage collector is in place, you should see patterns where the memory
increases until the garbage bin is full... then, memory is fully released. Also, a refresh should not keep any memory (below).

Here are some examples that cause memory leaks, along with their solutions:
Creation of DOM objects
This will cause two memory leaks... a circular reference and a DOM leak:
function createDiv() {
var oDiv = document.createElement('div');
oDiv.id = 'mydiv';
return oDiv;
}
var oDiv = createDiv();
oDiv.innerHTML = 'some content';
document.body.appendChild(oDiv);
oDiv.parentElement.removeChild(oDiv);
To repair this leak, place a try...finally around the return from the method, and pass the element to be removed to the
garbage collector.
function createDiv() {
var oDiv = document.createElement('div');
oDiv.id = 'mydiv';
try {
return oDiv;
}
finally{
oDiv = null;
}
}
var oDiv = createDiv();
oDiv.innerHTML = 'some content';
document.body.appendChild(oDiv);
sapphire.garbage.add( oDiv );
oDiv = null;
Circular references
This relates two simple DOM objects so if something happens on one, it affects the other. Refreshing the page will leave
all elements in memory:
<div id=oPrimary style="display:block">title</div>
<div id=oSecondary style="display:none">A sub title</div>
<script>
var oPri = document.getElementById( 'oPrimary' );
var oSec = document.getElementById( 'oSecondary' );
if ( oPri != null && oSec != null ) {
oPri.relatedElement = oSec;

file:///Users/aditya_saharay/Desktop/Lab%20Informatics/COTS%20Pro…8.6/Content/javascript/javascript_guide.htm#ApplicationResources Page 13 of 15
JavaScript Guide 15/02/24, 12:09 PM

oSec.relatedElement = oPri;
oPri.onclick = openClose();
oSec.onclick = openClose();
}
function openClose() {
var oEl = event.srcElement;
if ( oEl.style.display == 'block') {
oEl.style.display = 'none';
oEl.relatedElement.style.display = 'block';
}
}
</script>
What we must do is create a dispose function that is called when the page unloads. The dispose function must remove
any circular references, free variables where required, and stop DOM objects being stored globally:
<div id=oPrimary style="display:block">title</div>
<div id=oSecondary style="display:none">A sub title</div>
<script>
function setup() {
var oPri = document.getElementById( 'oPrimary' );
var oSec = document.getElementById( 'oSecondary' );
if ( oPri != null && oSec != null ){
oPri.relatedElement = oSec;
oSec.relatedElement = oPri;
oPri.onclick = openClose();
oSec.onclick = openClose();
oPri = null;
oSec = null;
}
}
function openClose() {
var oEl = event.srcElement;
if ( oEl.style.display == 'block') {
oEl.style.display = 'none';
oEl.relatedElement.style.display = 'block';
}
oEl = null;
}
function dispose() {
var oPri = document.getElementById( 'oPrimary' );
var oSec = document.getElementById( 'oSecondary' );
if ( oPri != null && oSec != null ){
oPri.relatedElement = null;
oSec.relatedElement = null;
oPri.onclick = null;
oSec.onclick = null;
oPri = null;
oSec = null;
}
}
window.addEventListener( 'load', setup );
window.addEventListener( 'unload', dispose );
</script>
For more examples, see:
http://www.bazon.net/mishoo/articles.epl?art_id=824
http://www.hedgerwow.com/360/dhtml/ie6_memory_leak_fix/
http://support.microsoft.com/kb/830555
http://www.javascriptkit.com/javatutors/closuresleak/index.shtml
http://javascript.crockford.com/memory/leak.html

Useful Utilities

As described in LabVantage JavaScript Utilities, LabVantage provides the Code Completion Utility and JavaScript Interrogator.

file:///Users/aditya_saharay/Desktop/Lab%20Informatics/COTS%20Pro…8.6/Content/javascript/javascript_guide.htm#ApplicationResources Page 14 of 15
JavaScript Guide 15/02/24, 12:09 PM

file:///Users/aditya_saharay/Desktop/Lab%20Informatics/COTS%20Pro…8.6/Content/javascript/javascript_guide.htm#ApplicationResources Page 15 of 15

You might also like