Home > Back-end >  Get element inside "block" relative of user click without IDs
Get element inside "block" relative of user click without IDs

Time:05-04

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.

  • Related