Reputation: 31
I try to make a very lite "jQuery like" selector, but I have problem to make it work on all classes, I tried with a for loop but because of the "return new" it brakes the loop.
JS
var $ = function(el){
var helpers = {
css: function(v){
(this.value).setAttribute('style',v);
},
replace: function(v){
(this.value).innerHTML = v;
console.log(this.value);
},
append: function(v){
(this.value).innerHTML = (this.value).outerHTML + ' ' + v;
}
};
function sel(el){
this.value = document.querySelector(el);
}
sel.prototype = helpers;
return new sel(el);
};
var sel1 = $('.sel1');
sel1.replace('<span>replaced</span>');
sel1.css("color:red");
HTML
<div class="sel1">test</div>
<div class="sel1">test</div>
<div class="sel1">test</div>
Upvotes: 3
Views: 171
Reputation: 4202
One of the powers of jQuery is the possibility to chain commands, which is actually done by holding a reference to the initial selector query. To get the basic idea, a simple kick-start implementation could look like this:
$$$ = function(selector) {
var Handler = function(selector) {
var elements = document.querySelectorAll(selector);
this.css = function(options) {
for (var i=0; i<elements.length; i++) {
for (var property in options) {
elements.item(i).style[property] = options[property];
}
}
return this;
};
this.hide = function() {
return this.css({display: 'none'});
};
this.show = function() {
return this.css({display: ''});
};
this.replace = function(html) {
for (var i=0; i<elements.length; i++) {
elements.item(i).innerHTML = html;
};
return this;
};
};
return new Handler(selector);
};
A simple working example for the code above could look like this:
$$$('div').css({border: '1px solid red', background: 'green'}).hide().show();
Since all internal functions return the current instance (return $this
), chaining calls to different actions is enabled.
Upvotes: 0
Reputation: 20741
You want to use the Document.querySelectorAll()
to get all the matches and not just the very first one. That's what jQuery does.
Obviously, this means 'value' is not a node, instead, it's a NodeList
(or null
). This changes the functions because they all have to deal with a list so you have to have some form of foreach()
to apply your function to each node (which, again, is what jQuery does, see the get() function as a good proof of this.)
Finally, if nothing matches, jQuery gets a null and the functions still work. This is because each function uses the foreach()
function and on null
, foreach()
does nothing. So you'd have to implement that foreach()
. Maybe something like this:
function foreach(list, func)
{
var max, i, n;
if(list) // make sure list is not 'null'
{
max = list.length;
for(i = 0; i < max; ++i) // go through the elements
{
n = list[i];
func(n); // call user function
}
}
}
Then the css
function would become something like this:
css: function(v)
{
foreach(this.value, function(n) { n.setAttribute('style', v); });
}
Note: if you make the foreach()
part of the helpers, make sure to use this.foreach()
to call it.
Upvotes: 1