Skip to content

Instantly share code, notes, and snippets.

@JustinSDK
Last active March 2, 2019 14:50
Show Gist options
  • Save JustinSDK/4705602 to your computer and use it in GitHub Desktop.
Save JustinSDK/4705602 to your computer and use it in GitHub Desktop.
The Example of "JavaScript Essence: Writing A DOM Library"

The Example of JavaScript Essence: Writing A DOM Library

(function(global) {
    var XD = function(selector, container) {
        return new XD.mth.init(selector, container);
    };
    
    var utils = {
        trim: function(text) {
  	    return (text || '').replace( /^(\s|\u00A0)+|(\s|\u00A0)+$/g, '');
	    },
        isArray: function(obj) {
		    return Object.prototype.toString.call(obj) === '[object Array]';
	    },
        isFunction: function(obj) {
		    return Object.prototype.toString.call(obj) === '[object Function]';
	    },
        each: function(obj, callback) {
            var length = obj.length,
                isObj = (length === undefined) || this.isFunction(obj);
            if (isObj) {
				for(var name in obj) {
					if(callback.call(obj[name], obj[name], name) === false ) {
						break;
					}
				}
			}
            else {
				for(var i = 0, value = obj[0];
					i < length && callback.call(obj[i], value, i) !== false; value = obj[++i] ) {}
			}
            return obj;
        },
        makeArray: function(arrayLike) {
			if(arrayLike.length != null) {
                return Array.prototype.slice.call(arrayLike, 0)
                             .filter(function(ele) { return ele !== undefined; });
			}
            return [];
		}
    };
    
   function extend(target, source) {
        utils.each(source, function(value, key) {
            target[key] = value;
        });
   }
   
   extend(XD, utils);
   XD.extend = extend;
   XD.props = {
        'for': 'htmlFor',
        'class': 'className',
        readonly: 'readOnly',
        maxlength: 'maxLength',
        cellspacing: 'cellSpacing',
        rowspan: 'rowSpan',
        colspan: 'colSpan',
        tabindex: 'tabIndex',
        usemap: 'useMap',
        frameborder: 'frameBorder'
    };
   
   XD.mth = XD.prototype = {
       init: function(selector, container) {
           // selector is a node.
           if(selector.nodeType) {
               this[0] = selector;
               this.length = 1;
               return this;
           }
       
           if(container && container[0]) {
               container = container[0];
           }
           else {
               container = document;
           }
           
           var elements = [];
           XD.each(selector.split(','), function(text) {
               text = XD.trim(text);
               if(text.charAt(0) === '#') {
                   elements.push(container.getElementById(text.substring(1)));
               }
               else if(text.charAt(0) === '<') {
                   elements.push(document.createElement(text.substring(1, text.length - 1)));
               }
               else {
                   XD.each(container.getElementsByTagName(text), function(element) {
                       elements.push(element);
                   });
                   
               }
           });
           XD.extend(this, elements);
           this.length = elements.length;
       },
       size: function() {
           return this.length;
       },
       isEmpty: function() {
           return this.length === 0;
       },
       each: function(callback) {
           return XD.each(this, callback);
       },
       html: function(value) {
           if(value === undefined) {
               return this[0] && this[0].nodeType === 1 ?
				        this[0].innerHTML : null;
           }
           else {
               return XD.each(this, function(element) {
                   if(element.nodeType === 1) {
                       element.innerHTML = value;
                   }
               });
           }
       },
       attr: function(name, value) {
           name = XD.props[name] || name;
           if(value === undefined) {
               return this[0] && this[0].nodeType !== 3 && this[0].nodeType !== 8 ?
                        this[0][name] : undefined;
           }
           else {
               return XD.each(this, function(element) {
                   if(element.nodeType !== 3 && element.nodeType !== 8) {
                       element[name] = value;
                   }
               });
           }       
       },
       val: function(value) {
           // currently, this function only deals with input elements
           if(value === undefined) {
               return this[0] && this[0].nodeName === 'INPUT' ? 
                       this[0].value : null;
           }
           else {
               return XD.each(this, function(element) {
                   if(element.nodeName === 'INPUT') {
                       element.value = value;
                   }
               });
           }
       },
       append: function(childs) {
           if(typeof childs === 'string' || childs.nodeType) {
               childs = XD(childs);
           }
           
           if(this.length === 1) { // only one parent node
               var parent = this[0];
               XD.each(childs, function(child) {
                   parent.appendChild(child);
               });
           }
           else if(this.length > 1){ // multiple parent nodes
               XD.each(this, function(parent) {
                   childs.each(function(child) {
                       // copy the node
                       var container = document.createElement('div');
                       container.appendChild(child);
                       container.innerHTML = container.innerHTML;
                       parent.appendChild(container.firstChild);
                   });
               });
           }
           return this;
       },
       remove: function() {
           return XD.each(this, function(element) {
               element.parentNode.removeChild(element);
           });
       }
   };
   
   XD.mth.init.prototype = XD.mth;

   global.XD = XD;
})(this);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment