问题
I ran yesterday in a problem with a jquery-selector I assigned to a variable and it's driving me mad.
Here is a jsfiddle with testcase:
- 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...
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
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...
回答1:
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.
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 .selector
property to refresh the snapshot for those.
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
回答2:
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
This was for jQuery 1.7.2 didn`t test refresh on filtered snapshots on higher versions
$.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.
回答3:
Jquery .selector is deprecated, it's better to remeber string with selector value to some variable at the moment when you assign
function someModule($selector, selectorText) {
var $moduleSelector = $selector;
var moduleSelectorText = selectorText;
var onSelectorRefresh = function() {
$moduleSelector = $(moduleSelectorText);
}
}
https://api.jquery.com/selector/
回答4:
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.
E.G.:
$('#parent .child).find('#foo').empty();
Maybe it can be useful to someone!
来源:https://stackoverflow.com/questions/11868899/how-can-i-refresh-a-stored-and-snapshotted-jquery-selector-variable