如何刷新存储和快照的jquery选择器变量

我昨天遇到了一个问题,一个jquery-selector我分配给一个变量,这让我很生气。

这是一个带有testcase的jsfiddle:

  • 将.elem分配给我的obj var
  • 将两个长度记录到控制台。 结果=> 4
  • 从DOM中删除#3
  • log obj to console =>删除的#3仍在那里,长度仍为4.我发现jquery查询是快照的? 变量而不能?不会? 得到更新
  • 将.elem登录到控制台..是的结果=> 3,#3消失了
  • 现在我更新.elem,新宽度为300
  • logging obj&obj.width给了我300 ..所以快照已更新? 有趣的是,4个div中有3个具有新的宽度,但删除的#3没有……

另一个测试:将一个li元素添加到domtree并记录obj和.elem。 .elem确实有新的li而obj没有,因为它仍然是旧的快照

http://jsfiddle.net/CBDUK/1/

有没有办法用新内容更新此obj? 我不想做一个新的obj,因为在我的应用程序中有很多信息保存在该对象中,我不想破坏…

是的,这是一个快照。 此外,从页面DOM树中删除元素并不会神奇地消除对元素的所有引用。

您可以像这样刷新它:

var a = $(".elem"); a = $(a.selector); 

小插件:

 $.fn.refresh = function() { return $(this.selector); }; var a = $(".elem"); a = a.refresh(); 

这个简单的解决方案不适用于复杂的遍历。 您将不得不为.selector属性创建一个解析器来刷新这些快照。

格式如下:

 $("body").find("div").next(".sibling").prevAll().siblings().selector //"body div.next(.sibling).prevAll().siblings()" 

就地迷你插件:

 $.fn.refresh = function() { var elems = $(this.selector); this.splice(0, this.length); this.push.apply( this, elems ); return this; }; var a = $(".elem"); a.refresh() //No assignment necessary 

我也喜欢@Esailija解决方案,但似乎this.selector有一些带filter的错误。 所以我修改了我的需求,也许对某人有用

这是因为jQuery 1.7.2没有在更高版本的过滤快照上测试刷新

 $.fn.refresh = function() { // refresh seletor var m = this.selector.match(/\.filter\([.\S+\d?(\,\s2)]*\)/); // catch filter string var elems = null; if (m != null) { // if no filter, then do the evarage workflow var filter = m[0].match(/\([.\S+\d?(\,\s2)]*\)/)[0].replace(/[\(\)']+/g,''); this.selector = this.selector.replace(m[0],''); // remove filter from selector elems = $(this.selector).filter(filter); // enable filter for it } else { elems = $(this.selector); } this.splice(0, this.length); this.push.apply( this, elems ); return this; }; 

代码不是那么漂亮,但它适用于我的过滤选择器。

不建议使用Jquery .selector,最好在分配时将带有选择器值的字符串记忆到某个变量

 function someModule($selector, selectorText) { var $moduleSelector = $selector; var moduleSelectorText = selectorText; var onSelectorRefresh = function() { $moduleSelector = $(moduleSelectorText); } } 

https://api.jquery.com/selector/

如果使用remove() ,它将只删除DOM的一部分而不是所有子项或相关的,而是如果在元素上使用empty()则问题就消失了。

例如:

  $('#parent .child).find('#foo').empty(); 

也许它对某人有用!