是否有可能创建一个jQuery插件,使得语法使用带点标记的嵌套函数而不需要传入参数?
例如:
$.fn.switchElement = {};
$.fn.switchElement.in = function() {
console.log(this); // logs $.fn.switchElement as an object containing a function called 'in'
this.attr('id'); // TypeError: this.attr is not a function (naturally; the above line shows us that it's not a jQuery object)
}
正如评论所提到的那样,试图通过像($(selector).switchElement.in();
这样的东西调用不起作用,因为对this
的引用不是编写jQuery插件所需要的;即this
需要成为传入的jQuery对象。
我是第一个承认,这是纯粹的语法,插件将完全正常接受" in"相反,$.fn.switchElement
函数的参数。
那就是说,我可以用一种模式来实现我的目标吗?
[编辑]
我在下面尝试了其中一个建议......当然没有完全理解它。这是我理解它的最佳尝试:
定义一个将成为插件的函数,称为"切换器"接受一个论点。在我的情况下,我打算传递一个jQuery对象,这是一个目标,所以我称之为我的" $ target"。
在切换器中是嵌套函数,称为(现在)switchIn()
。因为它在switcher
的范围内,所以它可以访问相同的this
。我理智地检查我有一个$target
然后我将this
(一个jQuery对象)附加到目标,然后返回this
以便于链接。
现在声明了这个函数,我们将它移动到一个任意称为" inner"的对象中。在" inner"内,我们设置函数to()
。 to()
是一个基本上switchIn()
的函数,但与范围内的this
以及$ target绑定。
我还没有完全理解第一个setTimeout。但在其中,内部(或函数嵌套)成为名为" switchElement"的插件。
在switcher
结束时,会返回this
,这又允许链接。
下一个$.fn[pluginName]
我也不明白。我没有设置一个名为" switchElement"的插件。其中包含一个名为"到"?
最后是额外有趣的部分。首先,我通过调用链接到jQuery对象并传入我的目标来初始化插件。这样可以在封闭类比中设置this
和$target
吗?这是否意味着在重新初始化之前$ target始终是目标?
在提供的示例代码中,我还包括一个额外的按钮单击,显示我希望我可以使用的语法,无需初始化。只需$(selector).switchElement.to($(target))
。这也是一个小提琴:http://jsfiddle.net/comrhqr4/1/
(function($) {
var pluginName = "switchElement";
var switcher = function switcher($target) {
var switchIn = function switchIn($target) {
console.log('invoking fn and sanity checking $target, which is ', $target);
if ($target) {
this.appendTo($target);
}
return this
}
var inner = {
"to": switchIn.bind(this, $target)
};
setTimeout(function() {
$.fn[pluginName] = inner
})
return this
};
$.fn[pluginName] = switcher;
$(document).on('click', '#switchTo1', function() {
console.log('clicked #switchTo1');
$('#unique').switchElement($('#container1'));
setTimeout(function() {
$('#unique').switchElement.to().css('color', 'blue');
})
});
$(document).on('click', '#switchTo4', function() {
console.log('clicked #switchTo4');
$('#unique').switchElement.to($('#container4'));
});
}(jQuery));
所以,还有一些问题:
答案 0 :(得分:1)
尝试使用Function.prototype.bind()
,setTimeout()
;注意,需要先调用$(element).pluginName([args])
(function($) {
var pluginName = "switchElement";
var Foo = function Foo(args) {
var fn = function fn(args) {
console.log(this, this.attr("id"));
if (args) {
this.html(args)
}
return this
}
var inner = {
"in": fn.bind(this, args)
};
setTimeout(function() {
$.fn[pluginName] = inner
})
return this
};
$.fn[pluginName] = Foo;
}(jQuery));
$("body").switchElement("123");
setTimeout(function() {
$("body").switchElement.in();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<body id="abc">
</body>
或者,使用$.extend()
var switchElement = { in : function() {
console.log(this, this.attr("id"))
}
}
$.fn.switchElement = function() {
return $.extend({}, this, switchElement)
};
$("body").switchElement().in()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<body id="abc"></body>