1) I have a task to implement jQuery on Javascript. But for some reason my method each doesn't work. For example when i write
$('.a').each(function (index) {$(this).append('<b>' + index + '</b>')})
it returns
DOMException: Failed to execute 'querySelectorAll' on 'Document': '[object Object]' is not a valid selector.
also I can't use this.each
inside of other functions. For example if I would have used each instead of forEach
inside append it would have not worked.
<script type="text/javascript">
(function() {
function $(selector) {
if (this instanceof $) return this.search(selector)
return new $(selector);
}
$.prototype = {
constructor: $,
length: 0,
search: function(selector) {
var that=this;
var elems=Array.prototype.slice
.call(document.querySelectorAll(selector));
elems.forEach(function(x,i){that[i]=x;});
this.length = elems.length;
return this;
},
append: function(text) {
if (text instanceof $) {
this[0].appendChild(text[0]);
for(var i = 1; i < this.length-1; i++) {
var p = text[0].cloneNode(true);
this[i].appendChild(p);
}
} else Array.prototype.slice
.call(this).forEach(function(x){
x.innerHTML = x.innerHTML + text;
});
return this;
},
each: function(callback){
for (var i=0;i<this.length;i++){
this[i]=callback.call(this,this[i])
};
return this;
},
}
window.$ = $;
}());
For example when i write
$('#id').each(function (index) {$(this).html('<b>' + index + '</b>')})
it returns
DOMException: Failed to execute 'querySelectorAll' on 'Document': '[object Object]' is not a valid selector.
You're doing $(this)
inside your each
callback. So that calls $
with this
set to the DOM element, which is not instanceof $
, and so you call new $(selector)
passing the DOM element. That ends up calling this.search(selector)
where, again, selector
is the DOM element. Then you call querySelectorAll(selector)
. QSA accepts strings, not DOM elements, and so the element gets converted to the string "[object Object]"
(or on some engines it'll be "[object HTMLElement]"
), and fails.
You can diagnose these errors by walking through the code statement-by-statement using the debugger built into your browser. If you're going to reimplement jQuery for some reason, you'll need to get in the habit of doing exactly that: Using the debugger heavily, identifying what's wrong, and fixing it.
In this case, for instance, you'll want to detect that selector
is not a string and handle that, e.g. something vaguely like this:
search: function(selector) {
var that=this, elems;
if (typeof selector === "string") {
elems = Array.prototype.slice.call(document.querySelectorAll(selector));
elems.forEach(function(x,i){that[i]=x;});
this.length = elems.length;
} else {
this[0] = selector;
this.length = 1;
}
return this;
},
But there will be lots and lots of other things you'll run into beyond that, which you'll need your debugger for.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With