我在空白页面上构建了一个站点,所以我的所有jQuery调用都类似于:
$('<div class="wtvr">Stuff</div>').appendTo(document.body);
$(':checkbox').map(function() { /* bunch of code */ });
等等。它工作得很好,但这是我的问题:我想将这一块代码放入一个div,在一个包含其他元素的页面上,问题是如果页面上有其他元素,我正在使用的代码将无法工作
我意识到我可以通过我的所有代码并将其重写为工作(即$(':checkbox')
到$('#container :checkbox')
),我的问题是:
我可以以某种方式设置一个上下文来基于我的所有jQuery调用吗?我想创建一个div并在div的上下文中运行所有代码。
我希望能够这样做:
$.context('#container');
//the following should do the same as $('#container').find(':checkbox').blah();
$(':checkbox').blah() // do like $('#container').find(':checkbox').blah();
//this should do the same as $('<div>Stuff</div>').appendTo('#container');
$('<div>Stuff</div>').appendTo(document.body);
你有两个陈述。我称之为“A”($(':checkbox').blah()
)和我称之为“B”($('<div>Stuff</div>').appendTo(document.body);
)。
从技术上讲,是的,你可以用这种方式重写“A”:
$(':checkbox', $('#container')).blah();
请参阅jQuery documentation以获得解释。更好(我会解释为什么很快)你可以(应该?)改为使用:
var context = $('#container');
$(':checkbox', context).blah();
要么
var context = $('#container');
context.find(':checkbox').blah();
但是对于语句“B”,你告诉jQuery明确地将<div>
附加到document.body - 所以不,没有办法让document.body
表示$('#container')
。并且 - 以防有人确实有这样做的狡猾方法 - 这不是一个好主意,因为反直觉,它会让每个读过代码的人都感到困惑(包括你,两个月后你回来改变东西)。
更好的方法是将您的“上下文”存储在临时变量中,如下所示:
var context = $('#container');
context.find(':checkbox').blah();
context.append('<div>Stuff</div>');
你会看到这种模式遍布整个地方。它是关于所有重要措施的“最少开销”解决方案:键入代码,读取代码,代码大小,执行速度,缓存利用率和自我文档。
当前的jQuery API中没有这样的context
功能。
我会使用curry返回一个返回jQuery的函数。
function makeContext( containerSelector ){
var jContext = $(containerSelector);
return function ( newQuery ){
return jContext.find( newQuery );
}
}
var context = makeContext('#container');
context(':checkbox').blah();
//or if you prefer
$.context = makeContext('#container');
$.context(':checkbox').blah();
然后,您可以设置上下文并在代码的相关部分中查找并替换“$”,并替换为“context”。如果jQuery有一个根上下文函数,问题就变成了,当你需要时如何逃避上下文?
另外,通过这种方式,您可以控制,更新并拥有多个上下文,例如:
var homeContext = makeContext('#homeElement');
var aboutContext = makeContext('#aboutElement');
//multiple context's living together
homeContext(':checkbox').blah();
aboutContext(':checkbox').foo();
//change context meaning later
homeContext = makeContext('home2Element');
homeContext(':checkbox').blah();
不,你不应该这样做。它使您的代码非常混乱。
将上下文放在变量中并不是一个很大的开销:
var c = $('#container');
c.children(':checkbox').blash();
c.children('<div>Stuff</div>').appendTo(document.body);
这几乎就是你能得到的。
它的工作原理是创建一个闭包并重新定义$作为一个完成你的意思的包装器。
在这个闭包之外,jQuery将继续正常运行,因此你不会破坏你注入代码的页面中的任何脚本。
(function(){
var fake_body = jQuery("#content"), $ = function(arg, context){
return jQuery(arg,context? context : fake_body);
};
// your code here
$(':checkbox').blah();
$('<div>Stuff</div>').appendTo(fake_body);
// end your code
})();