We need to support two jquery based image apis, jquery.lazy
to handle lazy loading of normal images, and jssor
to convert multiple images into a slider, which has it's own internal mechanism to lazy load images. To make this work we need to convert the src attribute of each image to either data-src (jquery.lazy) or src2 (jssor).
The html looks something like this:
<div id="campaign-content">
<div id="slide-show-1" class="embedded-slider-wrap">
<div>
<img src="/path/to/1.jpg" />
</div>
<div>
<img src="/path/to/2.jpg" />
</div>
</div>
<figure>
<img src="/path/to/3.jpg" />
</figure>
<div id="slide-show-2" class="embedded-slider-wrap">
<div>
<img src="/path/to/4.jpg" />
</div>
<div>
<img src="/path/to/5.jpg" />
</div>
</div>
</div>
The goal is to issue two xpath queries, one for all images within divs flagged as a slider-wrap (of which there may be multiple) and all images that are NOT contained within a slider-wrap div.
To reduce the complexity of the the xpath query, I was thinking it might be easier to query for just slide images, then query for all images, like:
$imagesSlide = $xpath->query(sprintf('//div[@id="%s"]//div[@class="embedded-slider-wrap"]//img', $id));
$imagesOther = $xpath->query(sprintf('//div[@id="%s"]//img', $id));
Then step through each one and set the correct attribute(data-src or src2). The problem I am having is, the xpath query for $imagesOther
returns all images (expected), whereas the xpath query for $imagesSlide
does not.
Also, I tried to do a NOT xpath query so I wouldn't have to do any extra processing with the ALL images query, but couldn't get it to work as expected either, it looks like:
$images = $xpath->query(sprintf('//div[@id="%s"]//img[not(ancestor::div/@class="embedded-slider-wrap")]', $id));
Solved the issue. I was approaching the xpath query the same way I approach jquery element selectors. What I didn't mention in the OP is the embedded-slider-wrap
class was not the only class applied to the div (honestly didn't think it mattered b/c jQuery can select elements having multiple classes).
Apparently, XPath won't match the query for an element based on class name if the element has multiple classes, instead you have to do the following:
// Element with multiple classes
<div class="embedded-slider-wrap some-other-class">
<img src="/path/to/image/1.png" />
// Non working Xpath query
//img[ancestor::div[@class="embedded-slider-wrap"]]//img
// Working Xpath query
//img[ancestor::div[contains(@class, "embedded-slider-wrap")]]