Before reading this answer, please refer to Sebastian Simon's comment above. Also, if you insist on using #id
s don't bother to consider this answer. The only time the use of #id
s is advantageous is in specific cases in the use of forms and form controls. The use (abuse?) of #id
in OP is ludicrous, please refer to charlietfl's comment above.
Avoid hard coding unique content like text or urls. Define unique content in a data structure (ex. array and/or object) outside of your functions so you can change them without touching the rest of the code. Of course event handlers (functions designed to run when an event occurs) only pass on the Event Object (ex. clickHandler(event)
), but there are workarounds such as wrapping the event handler definition in another function -- this function is known as a closure.
In the following example there is a closure init(string, array1, array2)
which has three required parameters:
- Generic:
string
Descriptive: listener
| a selector string of a single element that contains all of the <img>
s
/*Examples*/ "main", "body", ".images", "#try_Not_To_Use_Ids_They_Criiple_U"
- Generic:
array1
Descriptive: srcArray
| an array of urls that point to images
- Generic:
array2
Descriptive: txtArray
| an array of texts for captions
These parameters are defined outside of init()
so you won't have to change anything but these 3 parameters if the need arises. There are a couple of requirements in the HTML layout as well:
- The number of
<img>
s, and the .length
of both srcArray
and txtArray
must be equal. event.target
property will determine exactly which <img>
was clicked and will be referenced as clicked
.
- Each
<img>
must be followed by an element that can contain text. These elements will generically referenced as clicked.nextElementSibling
/*Example*/ <div></div>, <figcaption></figcaption>, <h6></h6>,....
- All
<img>
and .nextElementSibling
s must be within the listener
(referenced element in parameter 1).
This example is very agnostic. #id
s and .class
es are never needed and the amount of <img>
s is virtually unlimited (initially and dynamically).
Details are commented in example
const srcArray = ['https://static.wikia.nocookie.net/disney/images/6/65/Profile_-_General_Grievous.png/revision/latest?cb=20190313134830', 'https://pbs.twimg.com/profile_images/3103894633/e0d179fc5739a20308331b432e4f3a51.jpeg', 'https://pbs.twimg.com/profile_images/639566884807901185/LFKhqvgo_400x400.jpg'];
const txtArray = ['General Grievous', 'Darth Vader', 'Kylo Ren'];
function init(listener, srcA, txtA) {
// Reference listener
const parentNode = document.querySelector(listener);
/*
Collect all <img>s within listener into a NodeList
(referenced as imgList)
for Each <img> in imgList add [data-idx] attribute and
set the value to it's index number
Result: <img data-idx="0">, <img data-idx="1">,...
*/
/* Note: if in the future you are to dynamically add
<img>s and caption elements, move the next two lines
of code into clickHandler()
*/
const imgList = parentNode.querySelectorAll('img');
imgList.forEach((img, index) => img.dataset.idx = index);
// Event handlers pass the Event Object by default
function clickHandler(event) {
// Reference of the specific element user has clicked
const clicked = event.target;
// if user clicked an <img>...
if (clicked.matches('img')) {
/*
- get it's [data-idx] value and convert it into a
real number...
- get the url from srcArray at that [data-idx]
number and set <img> [src] with it...
- get the text string from txtArray at that
[data-idx] number and inset it into the element
that follows <img> (<figcaption> in this example)
Result:
<img src="https://pbs.twimg.com/profile_images/639566884807901185/LFKhqvgo_400x400.jpg" data-idx="2">
<figcaption>Kylo Ren</figcaption>
*/
let idx = parseInt(clicked.dataset.idx);
clicked.src = srcA[idx];
clicked.nextElementSibling.textContent = txtA[idx];
}
};
// Register parentNode as the click listener
parentNode.onclick = clickHandler;
};
/*
Run init()
1. Passing selector of "main" as the listener
2. Passing the predefined string arrays
3. All <img>s within parentNode/listener will have
[data-idx] = index position number
4. listener will be registered to the 'click' event
*/
init('main', srcArray, txtArray);
body {
font: 2ch/1.25 Consolas
}
main {
display: flex;
justify-content: space-between;
width: 90vw;
height: 90vh;
padding: 10px;
}
figure {
margin: 5px;
}
img {
display: block;
width: 150px;
height: 150px;
cursor: pointer;
}
figcaption {
text-align: center;
}
<main>
<figure>
<img src='https://via.placeholder.com/150'>
<figcaption></figcaption>
</figure>
<figure>
<img src='https://via.placeholder.com/150'>
<figcaption></figcaption>
</figure>
<figure>
<img src='https://via.placeholder.com/150'>
<figcaption></figcaption>
</figure>
</main>