static void

Webpage tips

Multiple IE versions

ppk discussion and older zips; IE 3-6 with installer
Expression Web SuperPreview (free IE6-7-8 viewer from Microsoft)

Meta Tags

Set these in the HTTP header (asp: Response.AddHeader) or put them as META tags in the <HEAD>.Force a page to refresh every time it is viewed (the Pragma is HTTP 1.0, Cache-Control is HTTP 1.1).

<meta http-equiv="Expires" content="0">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">

Javascript object detection

In javascript, an object that isn't defined is actually undefined, not null. The following show the different checks which will indicate whether a top level object exists. Note top-level global objects are actually properties of the window (self) object and you usually need to specify it (otherwise it unhelpfully throws an exception because it's undefined).

//only form to not need self.
if (typeof (MayNotExist) != "undefined") MayNotExist += 1;
            
//weak checking against null
if (self.MayNotExist != null) MayNotExist += 1;
        
//strong checking undefined
if (self.MayNotExist !== undefined) MayNotExist += 1;

//simple
if (self.MayNotExist) MayNotExist += 1;

Javascript objects

See here

var obj = {}; //same as = new Object();
var arr = []; //same as = new Array();

//initialize if does not exist (defined in another js file?)
window.myNamespace = window.myNamespace || {};

//object literal
var person = {
    name: "Martin", //use : not = and append the comma
    toString: function() {
        return "I am " + this.name;
    }
};

//anonymous functions can auto-excute
(function() {
    var name = document.getElementById("text").value;
    function copy() {
        document.getElementById("out").value = name;
    }
     
    copy();
}());

//revealing module pattern
var revealingModulePattern = function(){
	function privateCopy() { } //not in object notation
	function willBePublicCopy() { }
	return { //return an anonyomous object
		publicVar: willBePublicCopy() //alias what you make public
	}
}();

Cross Browser Events

Use an addEvent (eg mu.addEvent). Attached events will leak memory (esp. in IE6), so remove them in document.onunload.
Cross-browser event handlers should start like this...

function name(e) {
	e = e || event;
	var target = e.target || e.srcElement;
}

To stop bubbling events up...

e.cancelBubble = true;
if (e.stopPropogation) e.stopPropogation();

To cancel an action (eg onSubmit)...

e.returnValue = false;
if (e.preventDefault) e.preventDefault();
return false;

GetElementsByClassName()

FF3+ supports getElementsByClassName so always use it if available. This (simplified) version gets all elements with the class name in a document. There's a version which only gets descendants of a node (using prototype) here. (document.getElementsByTagName ( "*" ) does not work in IE5).

if(!document.getElementsByClassName) {
	document.getElementsByClassName = function ( class_name ) {
	    var ret_obj = new Array(), j = 0, findclass=  ' ' + class_name + ' ';
	    var all_obj = document.getElementsByTagName("*");
	    if (all_obj.length == 0 && document.all) all_obj= document.all;
	    for (var i = 0; i < all_obj.length; i++ ) {
	        var thisclass= all_obj[i].className;
	        if (thisclass) {
	            thisclass= ' ' + thisclass.toString() + ' ';
	            if ( thisclass.indexOf ( findclass )  != -1 ) {
	                ret_obj[j++] = all_obj[i];
	            }
	        }
	    }
	    return ret_obj;
	}
}

Forms: No back button/ Submit Once

Stop repeated clicks of submit. And protect against users pressing the back button.
The IE extension window.onbeforeunload is also available in Mozilla/Firefox. It doesn't stop the user, but the warning is better than over-complicated server-state checks or ActiveX webbrowsers.
Set window.onbeforeunload = null in the submit and navigation code (e.g. navigation links).
Here setWait() generates some HTML with a message. A simpler alternative is to show a hidden div (con: if styles disabled, div always visible). There's another version of this in mu2.js.

window.onbeforeunload = bunload;
document.forms[0].onsubmit= SetWait;
function bunload() {
    return "Please use the menu to navigate.\n
IF YOU EXIT NOW YOU WILL LOSE YOUR SESSION";
}
function setWait() { //onsubmit events
    window.onbeforeunload = null; //allows them to exit page
    var form= document.forms[0];
    form.style.display= "none";
    var body = document.getElementsByTagName("body")[0];
    body.className= "Wait";
    var msg= document.createElement("div");
    msg.className= "WaitMsg";
    var Message= "Please wait...";
    if (document.createTextNode) {
        var tn= document.createTextNode(Message);
        msg.appendChild(tn);
    } else {
        msg.innerText= Message;
    }
    body.appendChild(msg);
}

And the styles (uncomment image if required).

body.Wait {
cursor: wait;
/*background-image: url(/images/pleasewait.gif);
background-repeat: no-repeat;
background-position: center;*/
height: 90%;
width: 90%;
}
div.WaitMsg {
background-color: #B2B2B2;
position: absolute;
left: 30%;
top: 30%;
width: 30%;
font-size: large;
padding: 15px;
-moz-border-radius: 12px;
}

Rounded corners

I [over-]use -moz-border-radius but there's nifty corners (js + cs)

Pseudo-Modal Windows

IE4+ has a useful window.showModalDialog(url, arguments) method. The page reads input from the window.dialogArguments property (can be an array), and must set a returnValue property (you can't use the opener object). For cross-browser support, the solution below disables the parent window (source: Danny Goodman with minor changes).

//Disable parent screen when pop-up is used
//based on Danny Goodman's pseudo-modal dialog box api
// http://developer.netscape.com/viewsource/goodman_modal/goodman_modal.html
//popup onLoad="if (opener) opener.blockEvents()"
//nb: if it's slow loading, you might want it as first line in header
script, not onload
//popup onUnload="if (opener) opener.unblockEvents()"
// Since links in Internet Explorer 4 can't be disabled, preserve IE link
onclick
// event handlers while they're "disabled." Restore when reenabling the
main window.
var IELinkClicks
// Grab all Navigator events that might get through to form elements while
// dialog is open. For Internet Explorer, disable form elements.
function blockEvents() {
   if (gBrowserSniff() != "MSIE") {
      window.captureEvents(Event.CLICK | Event.MOUSEDOWN | 
    Event.MOUSEUP | Event.FOCUS);
      window.onclick = gDeadend;
   } else {
      disableForms();
   }
   window.onfocus = gCheckScreenEnabled;
}
// As dialog closes, restore the main window's original event mechanisms.
function unblockEvents() {
   if (gBrowserSniff() != "MSIE") {
      window.releaseEvents(Event.CLICK | Event.MOUSEDOWN | 
    Event.MOUSEUP | Event.FOCUS);
      window.onclick = null;
      window.onfocus = null;
   } else {
      enableForms();
   }
}
// Disable form elements and links in all frames for IE.
function disableForms() {
   IELinkClicks = new Array();
   var fr= top.frames;
   for (var h = 0; h < fr.length; h++) {
      for (var i = 0; i < fr[h].document.forms.length; i++) {
         for (var j = 0; j < fr[h].document.forms[i].elements.length; j++) {
            fr[h].document.forms[i].elements[j].disabled = true;
         }
      }
      IELinkClicks[h] = new Array();
      for (i = 0; i < fr[h].document.links.length; i++) {
         IELinkClicks[h][i] = fr[h].document.links[i].onclick;
         fr[h].document.links[i].onclick = deadend;
      }
   }
}
// Restore IE form elements and links to normal behavior.
function enableForms() {
    var fr= top.frames;
        for (var h = 0; h < fr.length; h++) {
      for (var i = 0; i < fr[h].document.forms.length; i++) {
         for (var j = 0; j < fr[h].document.forms[i].elements.length; j++) {
            fr[h].document.forms[i].elements[j].disabled = false;
         }
      }
      for (i = 0; i < fr[h].document.links.length; i++) {
         fr[h].document.links[i].onclick = IELinkClicks[h][i];
      }
   }
}
function gCheckScreenEnabled(){
        try {
        if (newWindow != null)
                newWindow.focus();
        } catch(e) { newWindow= null;unblockEvents(); } //if it
crashes/closes itself
}
function gDeadend() {
   if (newWindow && !newWindow.closed) {
      newWindow.focus();
      return false;
   }
}
function gBrowserSniff() { //very simple browser-sniffer
        if (document.all) return "MSIE";
        var strUA= navigator.appName;
  //mozilla or safari
        if (strUA.indexOf("Gecko") != -1) return "MOZILLA";
        return "OTHER";
}