Never been to CodeSnippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world (or not, you can keep them private!)

jQuery namespaced event binding/unbinding

// from a comment by Steven Bristol on errtheblog.com

I just wanted to share a really killer event handling tidbit:

Generally you do something like:

jQuery(’.class’).click(function(){//whatever});


Everyone knows this can be rewritten as:

jQuery(’.class’).bind(‘click’, function(){//whatever});


But sometimes you need to unbind something:

jQuery(’.class’).unbind(‘click’, function(){//});


The problem with this is that it will unbind all the click events, not just yours. So if multiple bits of javascript have a click event handler for ’.class’, unbinding removes them all. (This is because there is no way to identify an anonymous function.)

But jQuery is so good that there is a way to handle this: Namespacing your events:

jQuery(’.class’).bind(‘click.namespace’, function(){//}); 
jQuery(’.class’).unbind(‘click.namespace’);


or for reinitializing an element added via ajax:

jQuery(’.class’)unbind(‘click.namespace’).bind(‘click.namespace’, function(){//});

Find element position relative to other elements

http://particletree.com/notebook/finding-element-positions/

Insert in place without document.write

// http://www.sitepoint.com/blogs/2007/07/11/insert-in-place-without-documentwrite/

// So, given a syndication script with a fixed ID:
<script type="text/javascript" id="syndication" src="syndication.js"></script> 

// We can go from oldskool nastiness like this:
document.write('<p id="syndicated-content">Here is some syndicated content.</p>'); 

// To modern loveliness like this:

var newcontent = document.createElement('p'); 
newcontent.id = 'syndicated-content'; 
newcontent.appendChild(document.createTextNode('Here is some syndicated content.')); 
var scr = document.getElementById('syndication'); 
scr.parentNode.insertBefore(newcontent, scr); 

// We could even go a step further and remove the <script> ID, but in that case we would need a concrete method for identifying the specific element. We could do that by knowing its SRC:

var scripts = document.getElementsByTagName('script'); 
for(var i=0; i<scripts.length; i++) 
{ 
  if(scripts[i].src == 'http://www.mydomain.com/syndication.js') 
  { 
    //scripts[i] is the one 
    break; 
  } 
}

DomReady extension for prototype

This gives you a new event (onDOMReady).

Object.extend(Event, {
  _domReady : function() {
    if (arguments.callee.done) return;
    arguments.callee.done = true;

    if (this._timer)  clearInterval(this._timer);
    
    this._readyCallbacks.each(function(f) { f() });
    this._readyCallbacks = null;
},
  onDOMReady : function(f) {
    if (!this._readyCallbacks) {
      var domReady = this._domReady.bind(this);
      
      if (document.addEventListener)
        document.addEventListener("DOMContentLoaded", domReady, false);
        
        /*@cc_on @*/
        /*@if (@_win32)
            document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");
            document.getElementById("__ie_onload").onreadystatechange = function() {
                if (this.readyState == "complete") domReady(); 
            };
        /*@end @*/
        
        if (/WebKit/i.test(navigator.userAgent)) { 
          this._timer = setInterval(function() {
            if (/loaded|complete/.test(document.readyState)) domReady(); 
          }, 10);
        }
        
        Event.observe(window, 'load', domReady);
        Event._readyCallbacks =  [];
    }
    Event._readyCallbacks.push(f);
  }
});


Example:

Event.onDOMReady(function(){  
alert('DOM is loaded!');  
});

Opening window/tab helper library for Mozilla

var $window = {
	open_in_new_tab: function(url){
		getBrowser().selectedTab = getBrowser().addTab(url);
	},

	open_in_same_tab: function(url){
		top.content.document.location = url;
	},

	open_as_popup: function(url){
		var mypopup = window.open(url,'popuppage','toolbar=0,scrollbars=1,location=0,statusbar=0,menubar=0,resizable=1,width=700,height=400,left=30,top=30');
		mypopup.focus();
	},

	focus: function(obj){
		obj.focus();
	},

	click : function(aEvent,url){
		if (aEvent.button == 2){
			this.open_as_popup(url);
		}
		else if ((aEvent.ctrlKey) || (aEvent.button == 1) || (aEvent.metaKey)){
			this.open_in_new_tab(url);
		} 
		else {
			this.open_in_same_tab(url);
			this.focus(window._content);
			
		}
	}
}

Usage:
<toolbarbutton id="myid" label="my button"  class="toolbarbutton-1" onclick="$window.click(event,'http://localhost/');" />

Dynamically adding XUL elements

var mylib = {
       appendXulEl : function(parentId,nodeName,attribs){
		var elem = document.getElementById(parentId);
		var node = document.createElement(nodeName);
		for (attrib in attribs) {
			node.setAttribute(attrib, attribs[attrib]);
		} 		
		elem.appendChild(node);
	}
}


Usage:
mylib.appendXulEl('BrowserToolbarPalette', 'toolbarbutton', {'id':'MY_BUTTON_ID', 'label':'label for my button', 'tooltiptext':'button tooltip', 'class':'toolbarbutton-1', 'onclick':'alert("test")', 'context':''})

DOM output stream class

Simulating an output stream in Javascript

Pass the id of a DOM element to the constructor to get started. Call the clear() method first, if necessary. Then call the write() method as many times as needed. Finally, always remember to call flush() to force your output to appear.
// A little class for outputting HTML into a DOM element
function DOMStream(id) {
    this.elt = document.getElementById(id);
    this.buffer = [];
}
DOMStream.prototype.clear = function() { this.elt.innerHTML = ""; };
DOMStream.prototype.write = function() {
    for(var i = 0; i < arguments.length; i++) this.buffer.push(arguments[i]);
};
DOMStream.prototype.flush = function() {
    this.elt.innerHTML += this.buffer.join("");
    this.buffer.length = 0;
};

If it is not obvious, an important point of this class it to avoid inefficient repeated string concatenation. This is why it uses an array as a buffer, and why the write() method accepts multiple arguments--so you don't have to concatenate them yourself.
var out = new DOMStream("placeholder");
out.write('<h2>', section_title, '</h2>');
outputTable(out, data);  // Function defined elsewhere
out.flush();

Making Javascript DOM a Piece of Cake with the graft() Function

graft() allows us to build chunks of DOM documents using really simple object notation. Graft() will feel very familiar to anyone who makes extensive use of the JSON format.

I’ll dive right into an example here and show graft in its simplest use. Suppose we have a DOM element somewhere in our document that we want to insert stuff into:

<div id="mycontentdiv"></div>


If we wanted to insert a button into the above div element, we could use standard DOM in the following manner:

var mydiv = document.getElementById("mycontentdiv");
var btn = document.createElement("input");
btn.type = "button";
btn.value = "click me";
btn.onclick = function(){this.value="i have been clicked!";};
mydiv.appendChild(btn);


The above button example becomes the following using graft():

graft(
    document.getElementById("mycontentdiv"),
    ["input",
        {
            value:'click me',
            type:'button',
            onclick:'this.value="i have been clicked!";'
        }
    ]
);


// graft() function
// Originally by Sean M. Burke from interglacial.com
// Closure support added by Maciek Adwent

function graft (parent, t, doc) {

    // Usage: graft( somenode, [ "I like ", ['em',
    //               { 'class':"stuff" },"stuff"], " oboy!"] )

    doc = (doc || parent.ownerDocument || document);
    var e;

    if(t == undefined) {
        throw complaining( "Can't graft an undefined value");
    } else if(t.constructor == String) {
        e = doc.createTextNode( t );
    } else if(t.length == 0) {
        e = doc.createElement( "span" );
        e.setAttribute( "class", "fromEmptyLOL" );
    } else {
        for(var i = 0; i < t.length; i++) {
            if( i == 0 && t[i].constructor == String ) {
                var snared;
                snared = t[i].match( /^([a-z][a-z0-9]*)\.([^\s\.]+)$/i );
                if( snared ) {
                    e = doc.createElement(   snared[1] );
                    e.setAttribute( 'class', snared[2] );
                    continue;
                }
                snared = t[i].match( /^([a-z][a-z0-9]*)$/i );
                if( snared ) {
                    e = doc.createElement( snared[1] );  // but no class
                    continue;
                }

                // Otherwise:
                e = doc.createElement( "span" );
                e.setAttribute( "class", "namelessFromLOL" );
            }

            if( t[i] == undefined ) {
                throw complaining("Can't graft an undefined value in a list!");
            } else if(  t[i].constructor == String ||
                                    t[i].constructor == Array ) {
                graft( e, t[i], doc );
            } else if(  t[i].constructor == Number ) {
                graft( e, t[i].toString(), doc );
            } else if(  t[i].constructor == Object ) {
                // hash's properties => element's attributes
                for(var k in t[i]) {
                    // support for attaching closures to DOM objects
                    if(typeof(t[i][k])=='function'){
                        e[k] = t[i][k];
                    } else {
                        e.setAttribute( k, t[i][k] );
                    }
                }
            } else {
                throw complaining( "Object " + t[i] +
                    " is inscrutable as an graft arglet." );
            }
        }
    }

    parent.appendChild( e );
    return e; // return the topmost created node
}

function complaining (s) { alert(s); return new Error(s); }

Toggle Layers across browsers

// description of your code here

function toggleLayer(whichLayer) 
{
	if (document.getElementById) 
	{
		// this is the way the standards work
		var style2 = document.getElementById(whichLayer).style;
		style2.display = style2.display? "":"none";
	}
	else if (document.all)
	{
		// this is the way old msie versions work
		var style2 = document.all[whichLayer].style;
		style2.display = style2.display? "":"none";
	}
	else if (document.layers)
	{
		// this is the way nn4 works
		var style2 = document.layers[whichLayer].style;
		style2.display = style2.display? "":"none";
	}
}


Find All Elements By Class

// Javascript function that will return an array of elements based on DOM element, tag, and class name.
// For instance, getElementsByClassName(document, 'tr', 'INFO') will get all "tr" tags under the document node with the "INFO" class and return an array of them.

function getElementsByClassName(oElm, strTagName, strClassName){
var arrElements = (strTagName == "*" && document.all)? document.all : oElm.getElementsByTagName(strTagName);
	    var arrReturnElements = new Array();
	    strClassName = strClassName.replace(/\-/g, "\\-");
	    var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s|$)");
	    var oElement;
	    for(var i=0; i<arrElements.length; i++){
	        oElement = arrElements[i];
	        if(oRegExp.test(oElement.className)){
	            arrReturnElements.push(oElement);
	        }
	    }
	    return (arrReturnElements)
	}