I'm building a Wordpress site, where I've made it so that you can insert fullwidth images with parallax through the CKEditor by assigning the inserted images with a class. The script I've written replaces the found images with a div, and uses the source of the replaced image as background for the div. The rest is done by CSS. My problem is that so far I'm only able to get this to work with the first image that has the class.
I know where my code breaks down – it's when I replace the image with the div.
Here is my code:
if (document.getElementsByClassName('fullwidth-image').length > 0) {
let pictures = document.getElementsByClassName('fullwidth-image');
Array.prototype.forEach.call(pictures, function(e){
let imgUrl = e.src,
imgWrapper = document.createElement('div');
imgWrapper.classList.add('fullwidth-container');
imgWrapper.style.backgroundImage = 'url(' + imgUrl + ')';
e.replaceWith(imgWrapper);
});
}
If I comment out
e.replaceWith(imgWrapper);
then
console.log(e);
outputs all the images on the page, as it should. When it's in the code though, only the first image with class="fullwidth-image" gets outputted. How can I write this better?
The returned value from getElementsByClassName
is a live HTMLCollection
, which means it is automatically updated when the underlying document is changed.
Therefore, your iteration through this "array-like" object is affected whenever you replace one of the elements inside of it.
You can simply create a normal array out of the elements in the collection and iterate over that (which won't get messed up as you iterate through).
let pictureElements = document.getElementsByClassName('fullwidth-image');
const pictures = [...pictureElements]; // Uses object spread syntax
pictures.forEach(function(e) {
let imgUrl = e.src,
imgWrapper = document.createElement('div');
imgWrapper.classList.add('fullwidth-container');
imgWrapper.style.backgroundImage = 'url(' + imgUrl + ')';
e.replaceWith(imgWrapper);
});
div.fullwidth-container {
width: 100%;
height: 50px;
border: 1px solid black;
}
<img class="fullwidth-image" id="img1" src="" alt="No Image 1"/>
<img class="fullwidth-image" id="img2" src="" alt="No Image 2"/>
<img class="fullwidth-image" id="img3" src="" alt="No Image 3"/>
<img class="fullwidth-image" id="img4" src="" alt="No Image 4"/>
<img class="fullwidth-image" id="img5" src="" alt="No Image 5"/>
Notice, that all replaced elements should be a <div>
with a black border.