Reputation: 1386
UPDATE the current solution lives on this gist in case you ever need this type of functionality https://gist.github.com/jdaly13/5581538#file-gistfile1-js
I'm trying a little experimentation where I'm trying to override jQuery's core end method with my own method that just essentially adds functionality to it
for example if you are working with jQuery you might do something like this
$('h1.clickme').click(function () {
$(this).next('div').css("width", "+=200").parent().next().hide().end().end()
//this should traverse you back to the div after the h1 clicked
})
I want to override the jQuery end method by adding the ability to add a number parameter for example
.end(1)
would do the same as
.end().end()
Here is what I have so far
(function(){
// Define overriding method.
jQuery.fn.end = function(no_of_times){
var prevObject = "prevObject";
if (!(arguments.length) || (typeof no_of_times !== "number")) {
return this.prevObject || this.constructor(null);
} else {
if (no_of_times == 1) {
return this.prevObject.prevObject || this.constructor(null)
} else if (no_of_times == 2) {
return this.prevObject.prevObject.prevObject || this.constructor(null)
} else if (no_of_times == 3) {
return this.prevObject.prevObject.prevObject.prevObject || this.constructor(null)
} else {
//too many times can't type anymore
return this.prevObject || this.constructor(null);
}
}
}
})()
so I could call something like this
$('.promo-carousel').parent().prev().siblings('span').hide().end(2)
But obviously I don't think it's efficient to write out all those if statements Is there an easier way to do this? I'm sure the performance is about the same but I'm doing this more for readability sake
I thought of appending the prevObject variable with "prevObject" string based on the parameter passed something like this
if (!(arguments.length) || (typeof no_of_times !== "number")) {
return this.prevObject || this.constructor(null);
} else {
for (i=0; i <= no_of_times; i++) {
pObj += "prevObject."
}
var prevObject = pObj.slice(0, prevObject.length -1)
console.log(prevObject);
return this.prevObject
}
}
But that snippet of code above didn't work Any help is appreciated as always
Upvotes: 1
Views: 139
Reputation: 41533
Here's my solution : http://jsfiddle.net/QVxqY/
You don't have to reimplement any logic or keep track of the previous elements :
(function($){
var originalEnd = $.fn.end;
$.fn.end = function(n){
if(!n)
return originalEnd.call(this);
return $.fn.end.call(originalEnd.call(this), n-1);
}
})(jQuery);
Upvotes: 1
Reputation: 95022
You could just reuse the old method you are overriding:
(function($){
var oldfn = $.fn.end;
$.fn.end = function(times){
times = times || 1; // default to 1 if nothing or 0 is passed in
var ret = this;
for (i=0;i<times;i++) {
ret = oldfn.call(ret);
}
return ret;
};
})(jQuery);
Upvotes: 0
Reputation: 5892
Something similar should work.
var prevObject = this.prevObject;
for(i = 0; i<no_of_times; i++) {
prevObject = prevObject.prevObject;
}
return prevObject || this.constructor(null);
Upvotes: 1
Reputation: 53311
This should do the trick:
var prevObject = this.prevObject;
for(i = 1; i<no_of_times; i++) {
prevObject = prevObject.prevObject;
if(!prevObject) {
prevObject = this.constructor(null);
break
}
}
Just get the prevObject
of the prevObject
each iteration of the loop, until prevObject
is not found.
Upvotes: 2