On Dynamic Elements Creation, Again

It took me a while to finally conclude my previous project (Dynamic Element Creation), or at least… have another go at it.

But, thanks to the great and insightful comments of Matthias Miller, I came up with this interesting piece of code:

The syntax is somewhat similar to the way you nest elements in XHTML or HTML. You can choose to

/* Begin Type-detection functions */

//A set of helper functions for determining the type of ‘a’.
var Is={
        nt:function(a){
                return(a===null||a===undefined);
        },
        Function:function(a){
                return(typeof(a)===‘function’)?a.constructor.toString().match(/Function/)!==null:false;
        },
        String:function(a){
                return(typeof(a)===‘string’)?true:(typeof(a)===‘object’)?a.constructor.toString().match(/string/i)!==null:false;
        },
        Array:function(a){
                return(typeof(a)===‘object’)?a.constructor.toString().match(/array/i)!==null||a.length!==undefined:false;
        },
        Boolean:function(a){
                return(typeof(a)===‘boolean’)?true:(typeof(a)===‘object’)?a.constructor.toString().match(/boolean/i)!==null:false;
        },
        Date:function(a){
                return(typeof(a)===‘date’)?true:(typeof(a)===‘object’)?a.constructor.toString().match(/date/i)!==null:false;
        },
        HTML:function(a){
                return(typeof(a)===‘object’)?a.constructor.toString().match(/html/i)!==null:false;
        },
        Number:function(a){
                return(typeof(a)===‘number’)?true:(typeof(a)===‘object’)?a.constructor.toString().match(/Number/)!==null:false;
        },
        Object:function(a){
                return(typeof(a)===‘object’)?a.constructor.toString().match(/object/i)!==null:false;
        },
        RegExp:function(a){
                return(typeof(a)===‘function’)?a.constructor.toString().match(/regexp/i)!==null:false;
        }
};

//An improved version of the ‘typeof()’ function.
var type={
        of:function(a){
                for(var i in Is){
                        if(Is[i](a)){
                                return i.toLowerCase();
                        }
                }
        }
};

/* End Type-detection functions */

//Custom version of gEBC, so that it returns null if nothing is found.
document.getElementsByClass=function(a){
        var f=[],rE=new RegExp(‘(^|\\s)’+a+‘(\\s|$)’),els=document.getElementsByTagName(‘*’),i;
        for(i=0;i<els.length;i+=1){
                if(rE.test(els[i].className)){
                        f.push(els[i]);
                }
        }
        return(f.length)?f:null;
};

//Custom version of gEBTName, so that it returns null if nothing is found.
document.getElementsByTag=function(a){
        var r=document.getElementsByTagName(a);
        return(r.length)?r:null;
};

//shortcuts to the ‘getters’.
var by={
        Id:function(a){
                return document.getElementById(a);
        },
        Class:function(a){
                return document.getElementsByClass(a);
        },
        Tag:function(a){
                return document.getElementsByTag(a);
        }
};

/* Custom dollar function ($()) (searches by Ids, Class Names and Tag Names). */
//getElementsByClassName: $(‘aClassName’)
//getElementsByTagName: $(‘img’)
//getElementById: $(‘someId’)
function $(){
        var a=arguments,r=[],e,b,i;
        for(i=0;i<a.length;i+=1){
                e=a[i];
                if(Is.String(e)){
                        for(var j in by){
                                b=by[j](e);
                                if(b && Is.Array(b)){
                                        for(var k=0;k<b.length;k+=1){
                                                r.push(b[k]);
                                        }
                                }else if(b && !Is.Array(b)){
                                        r.push(b);
                                }
                        }
                }else{
                        r.push(e);
                }
        }
        return(r.length)?(r.length===1)?r[0]:r.unique():null;
}

//helper function that weeds out duplicates on the custom $ (dollar) function.
Array.prototype.unique=function(){
        var i,e,t=[];
        for(i=0;i<this.length;i+=1){
                e=this[i];
                t=this.slice(i+1,this.length);
                while(t.indexOf(e)>-1){
                        this.splice(t.indexOf(e)+i+1,1);
                        t.splice(t.indexOf(e),1);
                }
        }
        return this;
};

/* the de-Konstructor function */
//usage: document.getElementsByTagName("p").d();
//usage: document.getElementById("anId").d();
//usage: "img".d();
Array.prototype.d=Object.prototype.d=String.prototype.d=function(e){
        var t=type.of(this);
        switch(t){
                case "array":for(var i=0;i<this.length;i+=1){try{this[i].parentNode.removeChild(this[i]);}catch(e){}}break;
                case "html":try{this.parentNode.removeChild(this);}catch(e){}break;
                case "string":try{$(this).d();}catch(e){}break;
                default:break;
        }
};

/* Begin DOM custom functions (rigged with ‘event monitoring’)*/

//usage: someobject.before(anobject);
Object.prototype.before=function(a,e){
        try{a.parentNode.insertBefore(this,a);}catch(e){}queue.check();
};

//usage: someobject.after(anobject);
Object.prototype.after=function(a,e){
        try{this.before(a.nextSibling);}catch(e){}queue.check();
};

//usage: anobject.append(someobject);
Object.prototype.append=function(a,e){
        try{this.appendChild(a);}catch(e){}queue.check();
};

//usage: anobject.prepend(someobject);
Object.prototype.prepend=function(a,e){
        try{this.before(a,this.firstChild);}catch(e){}queue.check();
};

/* End DOM custom functions*/

//sets an object’s attribute (attributeName,attributeValue)
//if the attributeName is an ‘on-something’ event, it sends it to the queue.
Object.prototype.assign=function(aN,aV,e){
        if(aN.match(/^on\w*/)){
                queue.event(this,aN,aV);
        }else{
                try{this[aN]=aV;}catch(e){try{this.setAttribute(aN,aV);}catch(e){}}
        }
};

/* The Events Queue */
var queue={
//whenever a custom DOM insertion method is called, this function checks
//if the targets are in the document, if so, it sets the events properly.
        check:function(){
                var t,aN,aV;
                for(var i=0;i<this.targets.length;i+=1){
                        t=by.Id(this.targets[i]);
                        aN=this.targetEvents[i];
                        aV=this.targetFunctions[i];
                        if(t){
                                try{t[aN]=aV;}catch(e){try{t.setAttribute(aN,aV);}catch(e){}}
                                this.targets.splice(i,1);this.targetEvents.splice(i,1);this.targetFunctions.splice(i,1);
                        }
                }
        },
//pushes the object’s id, eventName and function into temporary arrays.
        event:function(obj,Name,Func){
                this.tag(obj);
                this.targets.push(obj.id);
                this.targetEvents.push(Name);
                this.targetFunctions.push(Func);
        },
//if the object doesn’t have an id, it creates one for it.
        tag:function(obj){
                if(Is.nt(obj.id)||obj.id===""){
                        var t=obj.tagName.toLowerCase();
                        obj.id=t+document.getElementsByTagName(t).length;
                }
        },
        targetEvents:[],
        targetFunctions:[],
        targets:[]
};

//Creates an HTML element from a string
//adapted from http://simon.incutio.com/archive/2003/06/15/javascriptWithXML
String.prototype.create=function(){
        return(document.createElementNS!==undefined)?document.createElementNS("http://www.w3.org/1999/xhtml",this):document.createElement(this);
};

/* The Konstructor function */
//usage: var asdf=["p","This link points to ",["a",{href:"http://example.com",onclick:function(){alert("Can\'t touch this.");return false;},title:"Clicking won't take you there, as the \'onclick\' function returns \'false\'."},"example.com"],". However, the onclick function won\’t let you go there."].k();
Array.prototype.k=function(){
        //creates the element
        var element=this[0].create();
        //if there is more stuff inside the Array
        if(this.length>1){
                for(var i=1;i<this.length;i+=1){
                        //if it’s an Object, it has attributes. Set them.
                        if(Is.Object(this[i])){
                                //attributes,attributeValue
                                var a=this[i],aV;
                                //attributeName in attributes
                                for(var aN in a){
                                        aV=a[aN];
                                        //if you’re creating a ‘param’ element, this is a time saver:
                                        //['param',{'movie':'http://example.com/asdf.avi'},{}]
                                        if(this[0]==="param"){element.assign(‘name’,aN);element.assign(‘value’,aV);}
                                        else{element.assign(aN,aV);}
                                }
                        }
                        //if it’s an Array, parse it and then append it.
                        else if(Is.Array(this[i])){
                                var child=this[i].k();
                                element.appendChild(child);
                        }
                        //if it’s a String,
                        else if(Is.String(this[i])){
                                var txt=this[i].k();
                                element.appendChild(txt);
                        }
                }
        }
        return element;
};

//Returns a TextNode from a string.
String.prototype.k=function(){
        return document.createTextNode(this);
};

I’ll add more info later. I’m kind of busy right now, but I didn’t wat to delay this post any longer.

3 Comments

Post a Comment

Your email is never shared. Required fields are marked *