I'm trying to modify .offset()
so that it never returns undefined
, i.e. for invisible/hidden elements.
The problem that I'm having with that is that I don't know how to properly pass this
to the original method, to be honest. Breakpoint-debugging reveals that I keep getting Window
when it should be the element in question. Here's what I got:
(function( $ ){
var original = $.fn.offset;
$.fn.offset = function( elem, coordinates, pass ) {
console.log('step 1'); // successful.
console.log(this); // element confirmation.
var o = original(elem, coordinates, pass); // triggers an exception.
console.log('step 2'); // is never reached.
if (o === undefined ) {
console.log('step 3a');
return {};
}
else {
console.log('step 3b');
return o;
}
}
}( jQuery ));
[…]
$('#element').offset(); // method call.
And here's the exception:
Error in event handler for (unknown): TypeError: undefined is not a function
at jQuery.fn.extend.offset (chrome-extension://…/js/jquery-1.11.0.js:10109:10)
at $.fn.offset (chrome-extension://…/js/jquery-modifications.js:35:11)
I've tried different variations – original(arguments)
, this.original()
, original(this, …)
– but none worked. In this question an argument called elem
is used next to three more arguments – but I'm not sure why. Is it because the API mentions attributeName
, value
and a callback function? If so then my attempt should work, analogous to the .offset()
API. Looking at how jQuery defines these functions didn't help either because .fn.attr
doesn't even show up like .fn.offset
does.
As you said:
The problem that I'm having with that is that I don't know how to properly pass this to the original method, to be honest.
In order to change function scope (this) there are two Function Prototype methods, called call()
and apply()
References to documentation of these two methods:
So, your code should now looks like this:
var original = $.fn.offset;
$.fn.offset = function() {
var o = original.apply(this, arguments);
return typeof o === 'undefined' ? {} : o;
};
and
return typeof o === 'undefined' ? {} : o;
It's just a better (IMO) shorter version of:
if (typeof o === 'undefined') {
return {};
} else {
return o;
}