将复杂的jquery css选择器转换为用于缓存的上下文

在反馈之后,完全重写问题。

我有以下标记:

 

Title

bla

...

我可以访问:

  

Title

bla

...

使用:

 $('body > *:not(div#do-not-modify-me)'); 

我这样做,所以我可以得到身体的所有内容,除了具有id“do-not-modify-me”的div。

现在,让我们说我想构建一个函数,让另一个程序员选择正文中的任何东西,就像使用jquery选择一样。 另一个程序员不应该修改div#do-not-modify-me,但他也不应该关心它。

$('body > *:not(div#do-not-modify-me)')将被调用很多时间,所以我们将缓存它。

这个想法是:

 // TEST CODE windows.new_body = $('body > *:not(div#do-not-modify-me)'); function select(selector) { return $(selector, windows.new_body); } 

所以其他程序员应该能够做到:

 // TEST RESULT CODE select("p").css("color", "red"); 

它会在身体的所有

中显示红色,但不会包含在div#do-not-modify-me中。

TEST CODE不起作用,因为目前它对上下文结果的子项应用css(),而不是自己的结果。

EG:

 select("p").css("color", "red"); 

表现如下:

 $('body > * p :not(div#do-not-modify-me)').css("color", "red"); 

虽然期望的结果是:

 $('body > p :not(div#do-not-modify-me)').css("color", "red"); 

注意 :

 $('body > * :not(div#do-not-modify-me)').parent().css("color", "red"); 

不起作用,因为

div#do-not-modify-me变成了红色。

您如何在测试结果代码中获得结果? 您可以修改代码的任何部分。

我删除了之前编辑的所有内容,因为它们不再相关,您可以在编辑历史中阅读它们。
EDIT3
基本上问题是你无法缓存选择器。 这是因为$()函数返回匹配的对象,而不是未匹配的对象。 这意味着使用缓存选择器意味着缓存可能与真实DOM不同步。 即在这个简单的页面中:

 

foo

bar

 var context = $('body').children(':not(.bar)'); //this holds: 

foo

bar

$('div', context).append('

HAI

'); //context still is

foo

bar

even though it should be //

foo

bar

HAI

所以你必须每次重做选择,贝司你有两个选择:

 //reselect the non-editable area everytime function select(selector) { return $(selector, $('body').children(':not(div#do-not-modify-me)') ); } //or, check the selection against being in the reselectable area. function select(selector){ return $(selector).filter(function(){ return $(this).parents(':not(div#do-not-modify-me)'); }); } 

你应该尝试自己哪一个更快。 我不认为有任何其他方法可以确保您不在#do-not-modify-me div中搜索。

你可以做的其他事情,使这更容易(我认为更快)是在div中包装可编辑区域:

  

Title

那你就可以做到

 function select(selector) { return $(selector, $('#modify-me') ); } 

你说代码可以以任何方式修改,对吧? 为什么不把它想象成你想要搜索的内容而不是你不想搜索的内容。 将其余代码放在

然后将其用作上下文。 它不会赢得任何优雅奖项,但它很简单并且获得了Job Alone TM

我很确定你可以直接使用’context’,如下所示:

 context = $('body > *:not(div#do-not-modify-me)'); context.doStuff(); 

阅读扩展说明后,我会尝试拍摄:

 context = $('body > *:not(div#do-not-modify-me)'); $("*:first",context); 

你甚至可以这样做:

  context = $('body > *:not(div#do-not-modify-me)'); context.find( "*:first"); 

要获得元素数量,您可以执行以下操作:

 var len = context.length; 

要访问集合中的元素编号i,您可以使用:

 context.get(i); 

在api.jquery.com上有大量有用的信息,也读过这个可能你想要创建自己的选择器。

编辑:
之后,我看到了你最近的更新,我认为你正在寻找的是能力迭代上下文结果元素,所以它可以像我在这里提到的那样多次通过:

  for ( var i = 0; i < context.length; ++i) { $( context[i]).method( ); // do here you checks, adding, removing. } 

这看起来并不聪明,但是应该可行,你可以通过扩展$ .fn并为你的目的实现函数来封装它。 编辑#2:
让我们尝试另一种方式:

  (function($) { $.fn.tagName = function( ) { return this.get(0).tagName; }; $.fn.pick = function( tag) { return this.filter( function( ) { return $(this).tagName == tag; }); }; } })(jQuery); 

在此之后你可以做contex.pick(“p”),所以它会返回你结果集中的所有段落,但是这段代码是不完整的,所以你需要更多地查看jquery代码,例如在一个jquery代码中实现它你可以使用pick函数使用完整的jqueryfunction,可能你需要考虑使用xpath DOM解析器 。