We're trying to create our own Javascript library to replace jQuery and reduce overhead. We're wanting to call functions from the global scope using the this
keyword, but the script is breaking in our foreach loop. How do we callback an object inside or custom "each" function using our $(this).getAtt('data-src')
function rather than a.getAttribute('data-src')
this
is defaulting to the window's object. Here's a minimized version of our library
var $=(function(){
'use strict';
var c = function(w){
if(!w)return;
if(w==='document'){this.elems=[document];}
else if(w==='window'){this.elems=[window];}
else {this.elems=document.querySelectorAll(w);}
};
c.prototype.each = function(callback){
if(!callback || typeof callback !== 'function')return;
for(var i = 0, length = this.elems.length; i < length; i++){callback(this.elems[i], i);}return this;
};
c.prototype.setAtt=function(n,v){this.each(function(item){item.setAttribute(n,v);});return this;};
c.prototype.getAtt=function(n){return this.elems[0].getAttribute(n);};
var init=function(w){return new c(w);};return init;
})();
function loadImgs(){
$("img[data-src]").each(function(a,b){
console.log(a.getAttribute('data-src'));
console.log($(this).getAtt('data-src'));
});
}
And our minimized HTML :
<a onclick="loadImgs();">lazyload</a><br>
<img src="spacer.gif" alt=""/></div><img class="lazyLoad" data-src="replacer.jpg" alt="">
Pass the calling context you want (the element) to the getAttribute
method by using .call()
.
You also need the c
constructor to set the elems
property to the argument if the argument is an element:
} else if (w instanceof HTMLElement) {
this.elems = [w];
}
for (var i = 0, length = this.elems.length; i < length; i++) {
callback.call(this.elems[i], this.elems[i], i);
// ^^ "this" in callback
// ^^ first argument to callback
// ^^ second argument to callback
}
var $ = (function() {
'use strict';
var c = function(w) {
if (!w) return;
if (w === 'document') {
this.elems = [document];
} else if (w === 'window') {
this.elems = [window];
} else if (w instanceof HTMLElement) {
this.elems = [w];
} else {
this.elems = document.querySelectorAll(w);
}
};
c.prototype.each = function(callback) {
if (!callback || typeof callback !== 'function') return;
for (var i = 0, length = this.elems.length; i < length; i++) {
callback.call(this.elems[i], this.elems[i], i);
}
return this;
};
c.prototype.setAtt = function(n, v) {
this.each(function(item) {
item.setAttribute(n, v);
});
return this;
};
c.prototype.getAtt = function(n) {
return this.elems[0].getAttribute(n);
};
var init = function(w) {
return new c(w);
};
return init;
})();
function loadImgs() {
$("img[data-src]").each(function(a, b) {
console.log(a.getAttribute('data-src'));
console.log($(this).getAtt('data-src'));
});
}
<a onclick="loadImgs();">lazyload</a><br>
<img src="spacer.gif" alt="" /></div><img class="lazyLoad" data-src="replacer.jpg" alt="">