Reputation: 665
I have an HTML string that I'm trying to update attributes on, but I can't seem to see the changes. Here is a simplified example:
var source = '<html><head></head><body><img src="abc" /><img src="abc" /></body></html>';
$(source).filter('img').each(function () {
$(this).attr('src', '123');
});
// At this point if I look at source in a debugger
// I'd expect to see the src attributes as all being
// '123', but I still see them all as 'abc'.
How should this be written so that source is updated with the changes?
Upvotes: 1
Views: 1069
Reputation: 2432
Jquery uses an array of elements behind the scenes. In your example, this array looks something like ['html']
(in pseudo code), meaning that you only have one element (html). When you use filter, it takes this array removes all the elements that don't match your selector. For example, if you had a list of elements like this: ['div', 'img', 'div', 'img']
, using your original code
var only_images = $(source).filter('img');
would result in ['img', 'img']
having removed all of the 'div'
tags. That being said, since your example only has one element ['html']
, the result ends up being an empty array []
.
The find
method, however, searches all of the descendents for a match. That means every element in your string is matched against img
(except for the original parent element html
).
I don't know that I've done a good job of explaining it, but what you ultimately need to do is switch your code up and start using the find
method. Example code below:
var source = '<html><head></head><body><img src="abc" /><img src="abc" /></body></html>';
$(source).find('img').each(function () {
$(this).attr('src', '123');
});
Upvotes: 2
Reputation: 123739
This should work fine, but you need to reassign the html to the string back again or append to the DOM as the change doesn't make any effect here as selector is not a DOM element but a string.
var source = '<html><head></head><body><img src="abc" /><img src="abc" /></body></html>';
var $source = $(source);
$source.filter('img').each(function () {
$(this).attr('src', '123');
});
console.log($source.wrapAll($('<div/>')).parent().html());
//or
source = $source.wrapAll($('<div/>')).parent().html();
Or just do
$(source).filter('img').attr('src', function () {
return '123';
}).appendTo('someselector');
note instead of using an explicit .each you can make use of function argument for attr
as in the second example.
Upvotes: 2