I'm not entirely sure if this is possible, but here is my idea:
I have multiple blocks in my page, all of them are built the same and they have the same classes. Only the content in the blocks is different.
I can't / don't want to assign IDs because these blocks get generated by the backend and it's just not suitable to give each an individual ID.
I want to get relative (in the HTML) to where the user clicks the button another element near the button and store that in a variable.
So if my HTML looks like this:
<div >
<h3>My first Element 1</h3>
<p>Some text</p>
<p>Some text</p>
<div>
<div>
<button >Button 1</button>
</div>
</div>
</div>
<div >
<h3>My second Element 2</h3>
<p>Some other text</p>
<p>Some other tex</p>
<div>
<div>
<button >Button 2</button>
</div>
</div>
</div>
I want to get the h3 in a variable, but only in the scope of the block.
So when the user clicks Button 2
the variable would be My second Element 2
but when the user clicks Button 1
the variable would be My first Element 1
I think you get the point.
Is that possible to do without IDs? I assume for JS both blocks look the same. Is there any way to stay in the scope of where the user clicks?
When I select the button with querySelectorAll
and loop through the output then I get multiple results for my h3
(so a result for any button on the page).
This is an example with a single block with an ID to show how my other code would work.
document.getElementById("button").addEventListener("click", myScript);
function myScript() {
let result = document.getElementById("button").parentElement.parentElement.parentElement.firstElementChild.innerHTML.trim();
console.log(result)
}
<div>
<h3>My first Element 1</h3>
<p>Some text</p>
<p>Some text</p>
<div>
<div>
<button id="button" >Button 1</button>
</div>
</div>
</div>
The only part missing is to only select the button that get's actually clicked and get relative to that the h3
, and only a single h3
inside the block and not every h3
on the page.
This is my simplified code of the actual thing without IDs and multiple blocks:
let result;
let button = document.querySelectorAll(".classButton");
button.forEach(click => {
click.addEventListener("click", myScript);
})
function myScript() {
button.forEach(i => {
result = i.parentElement.parentElement.parentElement.firstElementChild.innerHTML.trim();
})
console.log(result)
}
<div >
<h3>My first Element 1</h3>
<p>Some text</p>
<p>Some text</p>
<div>
<div>
<button >Button 1</button>
</div>
</div>
</div>
<div >
<h3>My second Element 2</h3>
<p>Some other text</p>
<p>Some other tex</p>
<div>
<div>
<button >Button 2</button>
</div>
</div>
</div>
I either only get the last element or if I put the console.log inside the forEach both.
Any way of doing that?
Thanks!
I know the way of getting the content of the h3 might not be the best way, but that's another problem I can work on as soon as the other part works.
CodePudding user response:
When you specify a function to handle an event inside a loop then you have access to event and element both so you don't have to loop again
let result;
let button = document.querySelectorAll(".classButton");
button.forEach(click => {
click.addEventListener("click", getH1);
})
function getH1(e){
let textValue = e.target.parentNode.parentNode.parentNode.children[0].innerText
console.log(textValue)
}
<div >
<h3>My first Element 1</h3>
<p>Some text</p>
<p>Some text</p>
<div>
<div>
<button >Button 1</button>
</div>
</div>
</div>
<div >
<h3>My second Element 2</h3>
<p>Some other text</p>
<p>Some other tex</p>
<div>
<div>
<button >Button 2</button>
</div>
</div>
</div>
<div >
<h3>My second Element 3</h3>
<p>Some other text</p>
<p>Some other tex</p>
<div>
<div>
<button >Button 3</button>
</div>
</div>
</div>
<div >
<h3>My second Element 4</h3>
<p>Some other text</p>
<p>Some other tex</p>
<div>
<div>
<button >Button 4</button>
</div>
</div>
</div>
CodePudding user response:
Thanks to @CBroe's comment I got this solution:
let result;
let buttonEvent = document.querySelectorAll(".classButton");
let button = document.querySelector(".classButton");
buttonEvent.forEach(click => {
click.addEventListener("click", myScript);
})
function myScript() {
result = this.parentElement.parentElement.parentElement.firstElementChild.innerHTML.trim()
console.log(result)
}
<div >
<h3>My first Element 1</h3>
<p>Some text</p>
<p>Some text</p>
<div>
<div>
<button >Button 1</button>
</div>
</div>
</div>
<div >
<h3>My second Element 2</h3>
<p>Some other text</p>
<p>Some other tex</p>
<div>
<div>
<button >Button 2</button>
</div>
</div>
</div>
I'm not sure if this is the 100% best way, but it's working.