0

I'm trying to figure out how to add an alt-text attribute to an image by assigning a data attribute to the parent container of that image.

Basically, whatever text I add to data-alt, will be assigned as alt-text on the img element.

How can I write the attribute so that it's applied as alt-text to the image, and not the parent?

What I want to enter in my code editor:

<div class="image-parent" data-alt="hello world">
    <img src="path/to/image">
</div>

My desired result:

<div class="image-parent">
  <img src="path/to/image" alt="hello world">
</div>

Here's what I've tried, but I'm not understanding how to apply the data attribute to the child element of image.

let imgParentContainers = document.querySelector('.image-parent');
let dataAlt = imgParentContainers.setAttribute('data-alt', '');
<div class="image-parent" data-alt="alt text here">
  <img src="https://apkdoll.com/wp-content/uploads/2021/08/HOLLA-Live-Random-Video-Chat-MOD-APK.png">
</div>
Millhorn
  • 2,953
  • 7
  • 39
  • 77
  • What exactly do you believe [`setAttribute()`](https://developer.mozilla.org/en-US/docs/Web/API/Element/setAttribute) returns? (Hint: the answer is `undefined`). Why are you trying to assign it to a variable? – esqew Oct 18 '21 at 19:57
  • Currently, the attribute is being assigned to the parent (`image-parent`), but I need to see it assigned to the image, not the parent container. – Millhorn Oct 18 '21 at 19:59
  • You didn't answer my question. What do you expect `dataAlt` to be set to, given the right-hand expression and the fact that `setAttribute` always returns `undefined`? Wouldn't you expect that a method named `setAttribute` would do just that (set the value of an attribute)? – esqew Oct 18 '21 at 19:59
  • Basically, I'm creating an empty space to assign `alt-text`, but when the HTML parses, I want to see that "alt-text" assigned to the img selector, and not the parent. – Millhorn Oct 18 '21 at 20:00
  • @esqew I have updated my OP. – Millhorn Oct 18 '21 at 20:04
  • 2
    You keep repeating the question (but it's perfectly clear what you want to happen). esqew is trying to ask some basic questions so you think about what your flawed code actually does and learn something while fixing it yourself. –  Oct 18 '21 at 20:07
  • I know what he's trying to do, I'm just not sure how to answer. – Millhorn Oct 18 '21 at 20:08
  • You named the variable imageParentContainer**s** but `querySelector` only returns the first match. Then you aren't even trying to iterate over them, but if you used `querySelectorAll` that's what you actually have to do. Next you have to actually grab the data-alt part, but you aren't calling **g**etAttribute (or using `.dataset)`. You're also not selecting the image element at any point. –  Oct 18 '21 at 20:10
  • This is why I'm asking the question. I don't use methods like this often. I'm trying to work this on my own, but the OP is as far as I got. – Millhorn Oct 18 '21 at 20:14
  • You're missing two crucial steps: 1. reading the parent's `data-alt` attribute 2. picking the child –  Oct 18 '21 at 20:16
  • 1
    Here's a short version: https://jsfiddle.net/heL3x9j7/ –  Oct 18 '21 at 20:24

1 Answers1

1

You need a few improvements to get to your desired target state:

  1. It's not clear why you'd use setAttribute() to get data from an attribute. As its name implies, it is used solely for setting the value of an attribute. A better attempt would be to use getAttribute(), but in this case, since you're accessing a data-* element, you should probably use HTMLElement.dataset instead.
  2. Unless you anticipate having exactly one element with the class image-parent, you should definitely swap your use of querySelector for querySelectorAll to ensure you get a NodeList of any/all matches instead of just the first one found in the DOM. In this case, you'll also have to use a loop for both (a) all parent containers matching your .image-parent selector, and another for (b) each of the img elements within that container.
  3. Be a bit more specific with your CSS selector in your call to querySelector/querySelectorAll to avoid issues relating to trying to access attributes that don't exist by matching on elements that have the data-alt attribute in the first place.
  4. Your desired end result shows that the data-alt attribute no longer exists on the parent container element; if this is actually desired goal, you don't seem to have attempted to do so in your snippet. Use removeAttribute() for this.

let imgParentContainers = [...document.querySelectorAll('.image-parent[data-alt]')];
imgParentContainers.forEach(parentContainer => {
    [...parentContainer.querySelectorAll('img')].forEach(imgElement => {
        imgElement.setAttribute('alt', parentContainer.dataset.alt);
    });
    parentContainer.removeAttribute('data-alt');
});
<div class="image-parent" data-alt="alt text here">
  <img src="https://apkdoll.com/wp-content/uploads/2021/08/HOLLA-Live-Random-Video-Chat-MOD-APK.png">
</div>

In the future, you may find it useful to use your preferred search engine to research each individual component of your requirement (appended with your language of choice; JavaScript in this case) to get a better idea of the methods you should be looking to use to achieve your goals. For example, the following Google searches yielded several pre-existing threads on this site alone for each component of the solution:

esqew
  • 42,425
  • 27
  • 92
  • 132
  • I feel like if I knew all the answers to those questions... I wouldn't need SO. I use SO as a tool when I don't know where to turn. Sometimes, I don't know what I don't know. – Millhorn Oct 18 '21 at 21:57
  • @Millhorn You seem to have an understanding of what needs to be done, do you see an issue getting to the Google queries yourself? – esqew Oct 18 '21 at 22:04
  • No. Honestly, it's applying the concepts that I struggle with. – Millhorn Oct 18 '21 at 22:09
  • For example, this question above was supposed to be a repeatable example that I could use to apply [to this Codepen](https://codepen.io/r3hab/pen/MWvydJP), but I'm struggling with the implementation. – Millhorn Oct 18 '21 at 22:13
  • Nevermind... I said that and then I figured it out. Your guidance was very helpful though and I've taken some brain-notes on your suggestions. – Millhorn Oct 18 '21 at 22:15