After the last post, I found that it may be fun to write a wrapper for YUI in order to make it behave like jQuery. Therefore, the code below is clearly mainly for self-amusement and is not intended to be used in production projects. However, through coding this, I found that although the difference in design, but YUI is obviously capable to do what jQuery offers (if not more). I will not continue working on this so whoever interested may just copy and paste the code to further developing it.
/**
* Proof of concept : jQuery-like syntax in YUI
*/
(function() {
var yui_builder = (function(Selector, Element, DOM, Event) {
return function(_selector) {
var Result = function() {};
var init = function(_selector) {
var result = [];
if(typeof _selector == 'object') {
result = [ new Element(_selector) ];
} else {
result = query_elements.call(this, _selector);
}
return result;
};
var delegate = function(_scope, _function) {
return function() {
return _function.apply(_scope, arguments);
};
};
var query_elements = function(_selector) {
var result = new Result;
var elements = wrap_elements(Selector.query(_selector));
for(var i in elements) {
result[i] = elements[i];
}
return result;
};
var unwrap_elements = function(_elements) {
var result = [];
for(var i in _elements) {
result[i] = _elements[i].get('element');
}
return result;
};
var wrap_elements = function(_elements) {
var result = [];
for(var i in _elements) {
result[i] = new Element(_elements[i]);
}
return result;
};
return (function(_elements) {
_this = new Result;
_this.addClass = function(_class) {
for(var i in _elements) {
_elements[i].addClass(_class);
}
return this;
};
_this.append = function(_content) {
if(typeof _content == 'string') {
for(var i in _elements) {
_elements[i].set(
'innerHTML',
_elements[i].get('innerHTML') + _content
);
}
} else if(typeof _content == 'object') {
_elements[0].appendChild(_content);
}
return this;
};
_this.appendTo = function(_selector) {
var _parent = yui_builder(_selector);
for(var i in _elements) {
_elements[i].appendTo(_parent.get(0));
}
return this;
}
_this.attr = function() {
var result = this;
if(arguments.length == 1 && typeof arguments[0] == 'string') {
result = _elements[0].get(arguments[0]);
if(!result) {
result = undefined;
}
} else if(arguments.length == 1 && typeof arguments[0] == 'object') {
for(var i in _elements) {
for(var attribute in arguments[0]) {
_elements[i].set(attribute, arguments[0][attribute]);
}
}
} else if(typeof arguments[1] == 'function') {
for(var i in _elements) {
_elements[i].set(arguments[0], arguments[1].call(_elements[i].get('element'), i));
}
} else {
for(var i in _elements) {
_elements[i].set(arguments[0], arguments[1]);
}
}
return result;
};
_this.each = function(_callback) {
for(var i in _elements) {
_callback.call(_elements[i].get('element'), i, _elements[i].get('element'));
}
return this;
};
_this.eq = function(_index) {
return yui_builder(_elements[_index]);
};
_this.get = function() {
var result = [];
if(arguments.length == 0) {
result = unwrap_elements.call(this, _elements);
} else {
result = _elements[arguments[0]].get('element');
}
return result;
};
_this.hasClass = function(_class) {
var result = false;
for(var i in _elements) {
if(_elements[i].hasClass(_class)) {
result = true;
break;
}
}
return result;
};
_this.html = function() {
var result = this;
if(arguments.length == 0) {
result = _elements[0].get('innerHTML');
} else {
_elements[0].set('innerHTML', arguments[0]);
}
return result;
}
_this.index = function(_subject) {
var result = -1;
for(var i in _elements) {
if(_elements[i].get('element') === _subject) {
result = i;
}
}
return result;
};
_this.removeClass = function(_class) {
for(var i in _elements) {
_elements[i].removeClass(_class);
}
return this;
}
_this.size = function() {
return _elements.length;
};
_this.toggleClass = function() {
if(arguments.length == 0) {
for(var i in _elements) {
if(_elements[i].hasClass) {
_elements[i].removeClass(arguments[0]);
} else {
_elements[i].addClass(arguments[0]);
}
}
} else {
for(var i in _elements) {
if(arguments[1]) {
_elements[i].addClass(arguments[0]);
} else {
_elements[i].removeClass(arguments[0]);
}
}
}
return this;
};
_this.val = function() {
var result = this;
if(arguments.length == 0) {
result = this.attr('value');
} else {
for(var i in _elements) {
this.attr('value', arguments[0]);
}
}
return result;
};
(function() {
for(var i in _elements) {
_this[i] = _elements[i];
}
}).call(_this)
return _this;
}).call(this, init.apply(this, arguments));
}
})(YAHOO.util.Selector, YAHOO.util.Element, YAHOO.util.Dom, YAHOO.util.Event);
})();
Most of the implemented functions are similar to what jQuery offers, therefore to use the yui_builder:
(function($) {
// everyone loves $ function
$(document.createElement('a'));
.attr('href', 'test')
.html('test')
.appendTo(document.body);
})(yui_builder);