Reputation: 1813
Is it possible to use jQuery to find all the background images on a page? My original plan was to loop through every element using:
jQuery("*").each(function() { ... });
and then check whether each element had a property set for .css("background-image")
However this doesn't seem to work. jQuery("*")
doesn't seem very performant.
Is there a better way?
Upvotes: 0
Views: 643
Reputation: 253318
While I realise that this question has already been answered, and has an accepted answer, it seems worth pointing out that the currently-accepted solution will only reliably inform you of background-image
s set using the in-line style
attribute.
to access those background-image
s of elements that are assigned via external style sheets the following is more reliable:
// here we're retrieving all elements on the page,
// by passing a wildcard ('*') to the
// document.getElementsByTagName() method:
var elems = document.getElementsByTagName('*'),
// creating an empty Array to hold the found
// background-images:
backgrounds = [];
// creating a for loop to iterate over the elements,
// initialising the i variable to 0 (as JavaScript
// indices start from zero), len is initialised as
// as the length of the elems Array;
// while len is less than the length of elements,
// the loop will run, incrementing the i variable
// each time in order to iterate over the Array:
for (var i = 0, len = elems.length; i < len; i++) {
// here we use the window.getComputedStyle()
// method to retrieve the styles applied to the
// current element - in the Array of elements over
// which we're iterating - whether applied by CSS
// or via the style attribute. To retrieve a particular
// property-value, we use the getPropertyValue()
// method with the relevant property passed as
// an argument. As the default-value of background-
// image is 'none' we explicitly test that the
// retrieved property-value is not-equal to 'none':
if (window.getComputedStyle(elems[i], null).getPropertyValue('background-image') != 'none') {
// here we push the property-value into the Array,
// using Array.prototype.push():
backgrounds.push(window.getComputedStyle(elems[i], null).getPropertyValue('background-image'));
}
}
// logging the values to the console:
console.log(backgrounds);
body {
background: transparent url(http://davidrhysthomas.co.uk/linked/astrid_avatar.png) 50% 50% no-repeat;
}
ul {
background: transparent url(http://davidrhysthomas.co.uk/img/dexter.png) 0 50% no-repeat;
margin: 0 0 1em 0;
}
section p {
background: transparent url(http://davidrhysthomas.co.uk/img/mandark.png) 100% 50% no-repeat;
margin: 0 0 1em 0;
width: 50%;
margin-left: 45%;
}
<div id="elem1">
<ul>
<li style="background-image: url(http://www.davidrhysthomas.co.uk/img/v_thumbnail.png)">List element one</li>
<li>List element two</li>
</ul>
</div>
<section>
<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It
has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop
publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
</section>
A rather more up-to-date approach, however, would be the following:
// here we initialise the NodeList of elements using the
// 'const' declaration, since it's not expected to change:
const elems = document.querySelectorAll('*'),
// and again using const to initialise the
// 'backgrounds' Array; here we convert the iterable
// NodeList returned from document.querySelectorAll()
// into an Array, using the spread operator; and then
// we use Array.prototype.filter() to filter that Array,
// which returns a subset of the original Array as a new
// Array:
backgrounds = [...elems].filter(
// as we don't require 'this', we're able to use an
// Arrow function expression for brevity; here
// current is reference to the current Node of the
// Array of Nodes over which we're iterating:
(current) => {
// retrieving the background-image of the 'current'
// element (as above):
let background = window.getComputedStyle(current, null).getPropertyValue("background-image");
// here we return Boolean true/false depending on
// the assessment here; if the background variable
// is not-equal to 'none' and has a length greater
// than zero, we return true (which retains the
// 'current' Node in the Array), otherwise we return
// false (which causes the 'current' Node to be
// discarded):
return background != 'none' && background.length > 0;
// next we use Array.prototype.map() to create a new
// Array based on the contents of the existing Array:
}).map(
// Again using an Arrow function; as the contents
// of the function aren't wrapped in braces we
// use the implicit return, which returns the
// retrieved background-image:
(current) => window.getComputedStyle(current, null).backgroundImage
);
console.log(backgrounds);
body {
background: transparent url(http://davidrhysthomas.co.uk/linked/astrid_avatar.png) 50% 50% no-repeat;
}
ul {
background: transparent url(http://davidrhysthomas.co.uk/img/dexter.png) 0 50% no-repeat;
margin: 0 0 1em 0;
}
section p {
background: transparent url(http://davidrhysthomas.co.uk/img/mandark.png) 100% 50% no-repeat;
margin: 0 0 1em 0;
width: 50%;
margin-left: 45%;
}
<div id="elem1">
<ul>
<li style="background-image: url(http://www.davidrhysthomas.co.uk/img/v_thumbnail.png)">List element one</li>
<li>List element two</li>
</ul>
</div>
<section>
<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It
has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop
publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
</section>
References:
Array.prototype.filter()
.Array.prototype.map()
.Array.prototype.push()
.CSSStyleDeclaration.getPropertyValue()
.document.getElementsByTagName()
.document.querySelectorAll()
....
) syntax.window.getComputedStyle()
.Upvotes: 2
Reputation: 14219
You could try the attribute contains word selector:
$('*[style~="background-image"]')
Upvotes: 1
Reputation: 2376
This works for me:
<div style="background-image:url('image1.jpg')">
<div style="background-image:url('image2.jpg')">
</div>
</div>
and the jquery:
$('*').each(function(i, item) {
console.log($(item).css('background-image'));
});
The console log outputs image1.jpg and image2.jpg, respectively.
And no, using the * selector is very, very slow. It literally checks everything (even inline elements that are very, very unlikely to have background images. You would be better off selecting individual tag types (like divs) or searching by class or id. Those will be much more efficient than the * selector.
Good luck.
Upvotes: 3