Remove last <img> inside a <div> [duplicate] - javascript

This question already has answers here:
How to remove last element from div?
(4 answers)
Closed 1 year ago.
I have <div> containing multiple <img>.
<div class="content">
<img src="img.png"/>
<img src="img.png"/>
<img src="img.png"/>
<img src="img.png"/>
</div>
The quantity <img> inside the <div> is dynamic.
I have a function that can remove all <img>. How do I modify the function to only remove last <img> inside the <div>?
document
.querySelectorAll(".content img")
.forEach((img) => img.remove());

querySelectorAll creates an array. So you just need to remove the last thing which is in the array. Something like this should work
const images = document.querySelectorAll(".content img")
images[images.length - 1].remove()

There are a number of ways to do what you are asking. Keep in mind that the return value of querySelectorAll is an array-like NodeList which can be accessed using standard array syntax, implements some array methods (forEach for example) or can be coerced to an array.
If you want to keep working with the result of querying all img elements in your div you can simply access the last element in the returned NodeList and remove it.
const images = document.querySelectorAll('.content img');
images[images.length-1].remove();
// or spread the NodeList to an array and pop
[...document.querySelectorAll('.content img')].pop().remove();
Alternatively, you can query the last img element directly using either :last-child or :last-of-type
document.querySelector('.content img:last-child').remove();
// or
document.querySelector('.content img:last-of-type').remove();
document
.getElementById('lastchild')
.addEventListener('click', () => document.querySelector('.content img:last-child').remove());
document
.getElementById('lasttype')
.addEventListener('click', () => document.querySelector('.content1 img:last-of-type').remove());
document
.getElementById('lastindex')
.addEventListener('click', () => {
imgs = document.querySelectorAll('.content2 img');
imgs[imgs.length - 1].remove()
});
document
.getElementById('pop')
.addEventListener('click', () => [...document.querySelectorAll('.content3 img')].pop().remove());
<div class="content">
<img src="https://source.unsplash.com/random/100x100/?sig=1"/>
<img src="https://source.unsplash.com/random/100x100/?sig=2"/>
<img src="https://source.unsplash.com/random/100x100/?sig=3"/>
<img src="https://source.unsplash.com/random/100x100/?sig=4"/>
</div>
<button type='button' id='lastchild'>Remove :last-child</button>
<hr>
<div class="content1">
<img src="https://source.unsplash.com/random/100x100/?sig=5"/>
<img src="https://source.unsplash.com/random/100x100/?sig=6"/>
<img src="https://source.unsplash.com/random/100x100/?sig=7"/>
<img src="https://source.unsplash.com/random/100x100/?sig=8"/>
</div>
<button type='button' id='lasttype'>Remove :last-of-type</button>
<hr>
<div class="content2">
<img src="https://source.unsplash.com/random/100x100/?sig=9"/>
<img src="https://source.unsplash.com/random/100x100/?sig=10"/>
<img src="https://source.unsplash.com/random/100x100/?sig=11"/>
<img src="https://source.unsplash.com/random/100x100/?sig=12"/>
</div>
<button type='button' id='lastindex'>Remove imgs[length-1]</button>
<hr>
<div class="content3">
<img src="https://source.unsplash.com/random/100x100/?sig=13"/>
<img src="https://source.unsplash.com/random/100x100/?sig=14"/>
<img src="https://source.unsplash.com/random/100x100/?sig=15"/>
<img src="https://source.unsplash.com/random/100x100/?sig=16"/>
</div>
<button type='button' id='pop'>Remove pop()</button>

If you want to use jQuery you can find last child and remove it.
Like this: $('.content').children('img').last().remove()
function deleteLastImg() {
$('.content').children('img').last().remove()
}
<script src="https://code.jquery.com/jquery-3.6.0.min.js"
integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
crossorigin="anonymous"></script>
<button onClick="deleteLastImg()" >Delet last image</button>
<div class="content">
<img src="img.png" />
<img src="img.png" />
<img src="img.png" />
<img src="img.png" />
<span>this is span</span>
</div>

Use .lastChild.remove();
let yourDiv = document.getElementById("yourDiv");
function yourFunction () {
yourDiv.lastChild.remove();
}
<button onclick="yourFunction()">Click me</button>
<div class="content" id="yourDiv">
<img src="https://images.ctfassets.net/hrltx12pl8hq/7yQR5uJhwEkRfjwMFJ7bUK/dc52a0913e8ff8b5c276177890eb0129/offset_comp_772626-opt.jpg?fit=fill&w=800&h=300"/>
<img src="https://images.ctfassets.net/hrltx12pl8hq/7yQR5uJhwEkRfjwMFJ7bUK/dc52a0913e8ff8b5c276177890eb0129/offset_comp_772626-opt.jpg?fit=fill&w=800&h=300"/>
<img src="https://images.ctfassets.net/hrltx12pl8hq/7yQR5uJhwEkRfjwMFJ7bUK/dc52a0913e8ff8b5c276177890eb0129/offset_comp_772626-opt.jpg?fit=fill&w=800&h=300"/>
<img src="https://images.ctfassets.net/hrltx12pl8hq/7yQR5uJhwEkRfjwMFJ7bUK/dc52a0913e8ff8b5c276177890eb0129/offset_comp_772626-opt.jpg?fit=fill&w=800&h=300"/>
</div>

Related

Puppeteer: How get img src inside nested selector?

I have a structure like this:
<div class="loaded active">
<img class="full" src="img1.jpg">
</div>
<div class="loaded">
<img class="full" src="img2.jpg">
</div>
<div class="loaded">
<img class="full" src="img3.jpg">
</div>
I need get link of img1.jpg.
I can get links for class="full":
const slkImg = '.full';
const imgs = await page.$$eval(slkImg, postLinks => postLinks.map(link => link.src));
but I don't know how do it for only img1.jpg.
As discussed in the comments,
page.$eval('.loaded.active .full', el => el.src)
works thanks to two things:
Using $eval rather than $$eval to select one element
Using .loaded.active .full to select the first .full descendent of the first .loading.active parent.

Unable to select all image elements

I'm using an intersection observer to implement lazy loading on my images. If I only select one image with the querySelector, then it works. But for some reason I can't get querySelectorAll to work. I also tried getElementsByClassName and this is still not working. Any solutions??
html:
<section class="section" id="section--2">
<div class="photo__container--two">
<img
data-src="portrait/4-vertical.JPG"
alt=""
class="fade-in img-vertical-lazy"
/>
<img
data-src="portrait/5-vertical.JPG"
alt=""
class="fade-in img-vertical-lazy"
/>
<img
data-src="portrait/6-vertical.JPG"
alt=""
class="fade-in img-vertical-lazy"
/>
</div>
</section>
JavaScript:
const lazyImages = document.querySelectorAll('.img-vertical-lazy');
const lazyLoading = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (!entry.isIntersecting) return;
entry.target.src = entry.target.getAttribute('data-src');
lazyLoading.unobserve(entry.target)
});
});
lazyLoading.observe(lazyImages);
According to the InstersectionObserver docs, the observe function receives a single node, not an array of nodes
You should rewrite the last line to this
lazyImages.forEach(image => lazyLoading.observe(image))

Inherit href destination from <a> to <img> tag using Vanilla JavaScript

I have a number of divs that possess the same className (.sampleClass) of which contain both an a and img element. I have managed to inherit the href value from a to img, however, due to these elements residing inside divs with the same className, the href inheritance is applied to all img elements using only the first href value of a identified inside of a div with .sampleClass.
HTML before JavaScript:
<div class="sampleClass">
<h2>text</h2>
<img src="./img/someImg.png" />
<p>text</p>
<a><span>text</span></a>
</div>
<div class="sampleClass">
<h2>text</h2>
<img src="./img/someOtherImg.png" />
<p>text</p>
<a><span>text</span></a>
</div>
The following JavaScript (vanilla) was used:
var aHref = document.querySelector(".sampleClass > a").getAttribute("href");
var img = document.querySelectorAll("img"); /* or (".sampleClass > img") */
img.forEach(function(inheritHrefImg) {
inheritHrefImg.setAttribute("href", aHref);
})
HTML after JavaScript:
<div class="sampleClass">
<h2>text</h2>
<img src="./img/someImg.png" href="example.html" /> /* this is correct */
<p>text</p>
<a><span>text</span></a>
</div>
<div class="sampleClass">
<h2>text</h2>
<img src="./img/someOtherImg.png" href="example.html" /> /* want href to be "random.html" */
<p>text</p>
<a><span>text</span></a>
</div>
I need a way to indicate img elements to only target the href of the a element within the div of which both that img and a resides.
Thanks in advance!
NOTE: Unfortunately giving an individual className to each div, although a solution, is not an option.
Just loop over the divs instead. Also note that your example is missing the first </div> end tag, I presume:
document.querySelectorAll('.sampleClass')
.forEach(sampleClass => {
sampleClass.children[1].setAttribute('href', sampleClass.children[0].children[0].getAttribute('href'));
});
console.log(document.body.innerHTML);
<div class="sampleClass">
<h2>text</h2>
<img src="./img/someImg.png" />
</div>
<div class="sampleClass">
<h2>text</h2>
<img src="./img/someOtherImg.png" />
</div>
But imgs should not have hrefs, I don't know what that's supposed to do; it would be much more elegant to simply enclose them in another dynamically created a, like this:
document.querySelectorAll('.sampleClass')
.forEach(sampleClass => {
const { href } = sampleClass.children[0].children[0];
const img = sampleClass.children[1];
img.remove();
const newA = document.createElement('a');
newA.href = href;
newA.appendChild(img);
const newAinsert = sampleClass.insertBefore(newA, sampleClass.children[1]);
});
console.log(document.body.innerHTML);
<div class="sampleClass">
<h2>text</h2>
<img src="./img/someImg.png" />
<p>text</p>
<span>text</span>
</div>
<div class="sampleClass">
<h2>text</h2>
<img src="./img/someOtherImg.png" />
<p>text</p>
<span>text</span>
</div>
I'm not sure how a href attribute on an img tag will help.. But one way you can do this is by querying for the parent divs and operating on it's children in a for loop.
Note: If you are using that href attribute on the img tag programmatically through JS, it may be better to make it a data-* attribute..
Sample:
var divs = document.querySelectorAll('.sampleClass');
divs.forEach(function(div) {
var aTag = div.querySelector('a');
var iTag = div.querySelector('img');
if (!aTag || !iTag) {
// This div does not have an image or anchor tag, skip
return;
}
iTag.setAttribute('href', aTag.href);
});
<div class="sampleClass">
<h2>text</h2>
<img src="./img/someImg.png" />
</div>
<div class="sampleClass">
<h2>text</h2>
<img src="./img/someOtherImg.png" />
</div>

jQuery. Add and remove elements working only once

It seemed like nothing special but...
I'm trying to add and remove div, add element function working as expected, but if I delete element, nothing else are working - I cannot add nor delete. And one more problem there - selectors using css class that are same for all elements, but event triggering only on first element.
Here is JS:
//Here i want to clone element and insert its after last element
$("div.addnewitem").on('click', function () {
var $d = $("div.item:first").clone();
$($d).insertAfter("div.item:last");
});
//Here i'm deleting element
$("div.deleteitem").on('click', function (event) {
$(event.target).closest("div.item").remove();
});
And HTML markup:
<div class="item">
<div class="itemphoto">
<img alt="" src="../img/woolrich.png">
</div>
<div class="bigshadow">
<img alt="" src="../img/bigshadow.png">
</div>
<!--This must add new element after last one-->
<div class="addnewitem">
<img alt="" src="../img/addnewitem.png">
</div>
<!--This must delete current div-->
<div class="deleteitem">
<img alt="" src="../img/deleteitem.png">
</div>
<div class="about">
<input type="text" class="link" placeholder="Ссылка на вещь..." name="item_url">
<input type="text" class="link" placeholder="Ссылка на изображение" name="item_image" />
<input type="text" class="name" placeholder="Вещь и бренд..." name="item_name">
<textarea class="review" placeholder="Короткое описание (около 120 символов)..." name="item_desc"></textarea>
<input type="text" class="pricestylist" placeholder="Цена (xxx руб/$)" name="item_price">
</div>
</div>
try the fiddle demo
first").clone(true); , the true was missing, it is withDataAndEvents attribute,
for more details, check clone()

Programmatically apply the image alt attribue as a class to parent element

I want to add as a class the image alt attribute to its container element. Markup:
<div class="field-group-our-people">
<div class="field-items even>
<img alt="John">
</div>
<div class="field-items odd>
<img alt="Kevin">
</div>
<div class="field-items even>
<img alt="Kate">
</div>
<div class="field-items odd>
<img alt="Martin">
</div>
</div>
To be like this:
<div class="field-group-our-people">
<div class="field-items even john>
<img alt="John">
</div>
<div class="field-items odd kevin>
<img alt="Kevin">
</div>
<div class="field-items even kate>
<img alt="Kate">
</div>
<div class="field-items odd martin>
<img alt="Martin">
</div>
</div>
My Jquery code(but not working):
//Add the image alt attribute as class for individual styling
$('.group_our_people .field-item').each(function() {
var att = $('.group_our_people .field-item img').attr('alt');
$(this).addClass(att);
});
What is wrong/missing in my code?
You should get the img that is child of the current div (on iteration):
var att = $(this).find('img').attr('alt');
The way you're doing (i.e. repeating the selector), you end up retrieving multiple values, and only the first one is taken into account. So, every div will get its class: "John".
$('.field-group-our-people .field-items img').each(function() {
$(this).parent().addClass( $(this).attr('alt') );
});
$('div.field-group_our_people div[class^=".field-items"] img').each(function()
{
var att = $(this).attr('alt');
$(this).parent().addClass(att);
});

Categories