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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11868899/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 07:27:24  来源:igfitidea点击:

How can I refresh a stored and snapshotted jquery selector variable

javascriptjqueryvariablesdomjquery-selectors

提问by Ralk

I ran yesterday in a problem with a jquery-selector I assigned to a variable and it's driving me mad.

昨天我遇到了分配给变量的 jquery 选择器的问题,这让我很生气。

Here is a jsfiddle with testcase:

这是一个带有测试用例的jsfiddle:

  • assign the .elem to my obj var
  • log both lengths to the console. Result => 4
  • Remove #3 from the DOM
  • log obj to the console => the removed #3 is still there and the length is still 4. I figured out that jquery query is snapshotted? to the variable and can't?won't? be updated
  • log .elem to the console.. yep Result => 3 and the #3 is gone
  • Now I update .elem with a new width of 300
  • logging obj & obj.width gives me 300.. So the snapshot has been updated ? What's interesting is that 3 of the 4 divs have the new width, but the removed #3 doesn't...
  • 将 .elem 分配给我的 obj var
  • 将两个长度都记录到控制台。结果 => 4
  • 从 DOM 中删除 #3
  • 将 obj 记录到控制台 => 删除的 #3 仍然存在并且长度仍然是 4。我发现 jquery 查询被快照了?到变量,不能?不会?被更新
  • 将 .elem 记录到控制台.. 是的 结果 => 3 并且 #3 消失了
  • 现在我用 300 的新宽度更新 .elem
  • logging obj & obj.width 给了我 300.. 所以快照已经更新了?有趣的是,4 个 div 中的 3 个具有新的宽度,但删除的 #3 没有...

Another test: Adding a li element to the domtree and logging obj and .elem. .elem does have the new li and obj doesn't, because it's still the old snapshot

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

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

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

Is there no way to update this obj with the new content? I don't want to make a new obj, because in my application there is a lot information saved in that object, I don't want to destroy...

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

回答by Esailija

Yeah, it's a snapshot. Furthermore, removing an element from the page DOM tree isn't magically going to vanish all references to the element.

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

You can refresh it like so:

您可以像这样刷新它:

var a = $(".elem");

a = $(a.selector);

Mini-plugin:

迷你插件:

$.fn.refresh = function() {
    return $(this.selector);
};

var a = $(".elem");

a = a.refresh();

This simple solution doesn't work with complex traversals though. You are going to have to make a parser for the .selectorproperty to refresh the snapshot for those.

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

The format is like:

格式是这样的:

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

In-place mini-plugin:

就地迷你插件:

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

回答by Roman M. Koss

I also liked @Esailija solution, but seems that this.selector has some bugs with filter. So I modified to my needs, maybe it will be useful to someone

我也喜欢 @Esailja 解决方案,但似乎 this.selector 有一些过滤器错误。所以我修改了我的需求,也许它会对某人有用

This was for jQuery 1.7.2 didn`t test refresh on filtered snapshots on higher versions

这是针对 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;
};

Code is not so beautiful, but it worked for my filtered selectors.

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

回答by Kattie

Jquery .selector is deprecated, it's better to remeber string with selector value to some variable at the moment when you assign

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

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

   var onSelectorRefresh = function() {
      $moduleSelector = $(moduleSelectorText);
   }
}

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

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

回答by Flaivo Luminol Zanardi

If you use remove()it will remove only a part of the DOM but not all the children or related, instead if you use empty()on the element the problem is gone.

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

E.G.:

例如:

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

Maybe it can be useful to someone!

也许它对某人有用!