
Useful JavaScript
Almost every time I've needed javascript, I've also needed to hide and show different elements on a page. By extending the built in objects using the code below, I have the ability to call hide() and show() on any element.
These are really just shortcuts to functionality already available.
Object.prototype.show = function()
{
this.style.display = 'block';
}
Object.prototype.hide = function()
{
this.style.display = 'none';
}
Object.prototype.destroy = function()
{
this.parentNode.removeChild(this);
}
Object.prototype.removeAllChildren = function()
{
while(this.childNodes.length)
this.removeChild(this.lastChild);
}
Type Checking and Array.IndeOf
// typoe detection taken from http://mattsnider.com/javascript/type-detection/
function isFunction(o) {return 'function' == typeof o;}
function isArray(o) {return isObject(o) && o.constructor == Array;}
function isBoolean(o) {return 'boolean' == typeof o;}
function isDate(o) {return isObject(o) && o.getMonth;}
function isDomElement(o) {return o && ('undefined' !== typeof o.childNodes || o.nodeType);}
function isEvent(o){return o && 'undefined' != typeof Event && o.eventPhase;}
function isNull(o) {return null === o;}
function isNumber(o) {return 'number' == typeof o && isFinite(o);}
function isObject(o) {return (o && 'object' == typeof o) || isFunction(o);}
function isSet(o) {return ((o || false === o || 0 === o) && ! isNull(o) && '' !== o && ! isUndefined(o));}
function isString(o) {return 'string' == typeof o;}
function isUndefined(o) {return 'undefined' == typeof o;}
//This prototype is provided by the Mozilla foundation and
//is distributed under the MIT license.
//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license
if (!Array.prototype.indexOf)
{
Array.prototype.indexOf = function(elt /*, from*/)
{
var len = this.length;
var from = Number(arguments[1]) || 0;
from = (from < 0)
? Math.ceil(from)
: Math.floor(from);
if (from < 0)
from += len;
for (; from < len; from++)
{
if (from in this &&
this[from] === elt)
return from;
}
return -1;
};
}
Easily create User Events
While not true user events, this is a quick and dirty way to make an event that calls multiple subscribers.
function userEvent()
{
this.listeners = new Array();
this.AddListener = addListener;
this.RemoveLister = removeListener;
this.CallListeners = callListeners;
function addListener(callbackFunction)
{
this.listeners[this.listeners.length] = callbackFunction;
}
function removeListener(callbackFunction)
{
var n;
while(n=this.listeners.indexOf(callbackFunction))
this.listeners.splice(n,1);
}
function callListeners(objThis)
{
for (var i=0; i<this.listeners.length; i++)
{
if (isFunction(this.listeners[i])) this.listeners[i](objThis);
}
}
}
Easy iPhone Navigation Object
Now using all of that from above, I've also created a nice navigation object for developing iPhone applications.
function navigation()
{
this.position = 0;
this.history = new Array();
this.Back = back;
this.Forward = forward;
this.NavTo = addNav;
this.AtEnd = atEnd;
this.AtBegin = atBegin;
this.OnChange = new userEvent();
function atBegin()
{
if (this.position == 1) return true;
return false;
}
function atEnd()
{
if ((this.history.length -1) == this.position) return true;
return false;
}
function back()
{
if (this.history.length == 1 || this.position == 1) return;
animateRightToLeft(this.history[this.position-1], this.history[this.position--]);
hideAddressbar();
this.OnChange.CallListeners(this);
}
function forward()
{
if ((this.history.length -1) == this.position) return;
animateLeftToRight(this.history[this.position +1],this.history[this.position++]);
hideAddressbar();
this.OnChange.CallListeners(this);
}
function addNav(div)
{
for(var i=this.position+1; i < this.history.length; i++) this.history[i].destroy();
this.history.length = this.position+1;
this.history[this.history.length] = div;
this.position++;
if (this.position == 1) { div.show(); return; }
animateLeftToRight(this.history[this.position], this.history[this.position - 1]);
hideAddressbar();
this.OnChange.CallListeners(this);
}
function animateLeftToRight(left, right)
{
// for now just show left and hide right, later make an animation to handle it
if (left) left.show();
if (right) right.hide();
}
function animateRightToLeft(right, left)
{
// for now just show right and hide left, later make an animation to handle it
if (right) right.show();
if (left) left.hide();
}
}
var nav = new navigation();
In an iPhone web application we load as much as possible in one shot and dynamically build different divs that the user navigates around to. By adding a nav.NavTo() call to every move around the user makes, we can keep a history of where that user has been and create forward and back buttons for them to go back through their actions.
You could easily add an auto enable function to both the forward and back buttons. (Simply hiding or showing here, but this could easily be adapted to to enabled or disabled image buttons.)
backbutton=document.getElementById('back');
forwardbutton=document.getElementById('forward');
backbutton.autoEnable = function()
{
document.getElementById('back').style.display = (nav.AtBegin()) ? "none" : "block";
}
forwardbutton.autoEnable = function()
{
document.getElementById('forward').style.display = (nav.AtEnd()) ? "none" : "block";
}
Note: This is where these are not true events and it would show as the "this" keyword refers to the window, not the element.

