2015-04-04 64 views
2

我试图修改.offset(),以便它永远不会返回undefined,即不可见/隐藏元素。如何在扩展jQuery方法时传递参数?

我遇到的问题是,我不知道如何正确地将this传递给原始方法。断点调试表明,当它应该是所讨论的元素时,我总是得到Window。下面是我的了:

(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. 

而这里的例外:

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) 

我已经尝试了不同的变化 - original(arguments)this.original()original(this, …) - 但没有奏效。在this question之后,在另外三个参数旁边使用了名为elem的参数 - 但我不确定原因。是否因为API提到attributeName,value和一个回调函数?如果是这样,那么我的尝试应该工作,类似于.offset() API。看看如何jQuery定义这些功能并没有帮助,因为.fn.attr甚至不显示像.fn.offset那样。

回答

4

至于你说:

说我与遇到的问题是,我不知道如何正确地把它传递给原来的方法,要诚实。

为了改变功能范围(本)有两个函数原型的方法,称为call()apply()

引用这两种方法的文档:

Function.prototype.call()

Function.prototype.apply()

所以,你的代码应该看起来像这样:

var original = $.fn.offset; 

$.fn.offset = function() { 
    var o = original.apply(this, arguments); 
    return typeof o === 'undefined' ? {} : o; 
}; 

return typeof o === 'undefined' ? {} : o; 

它只是一个更好的(IMO)较短的版本:

if (typeof o === 'undefined') { 
    return {}; 
} else { 
    return o; 
} 
+6

这是正确的,但你应该解释为什么** **和** *如何* 有用。 – 2015-04-04 12:20:31

+0

“这只是一个更好的(IMO)更短的版本[”]“我知道,我只是分裂了控制台日志的界限。 – WoodrowShigeru 2015-04-15 16:37:13