1

I'm just starting out with JavaScript although I have used a number of other languages previously. I'm finding the orientation pretty painful and I'd appreciate some guidance on how to access child elements within a forEach loop (or a jQuery .each loop). At this stage I don't really care whether the solution is JS or jQuery, I'm just trying to get something that works.

Say I have a node element that I have found using jQuery and I now have some processing to do on each row, which includes needing to find a child-element whose id contains an index related to the parent node in question:

$('.row').each((index, item) => {
    var name = item.getElementById(`#name-${index}`);
});

It seems that it should be straightforward to select the element using getElementById, but this results in an 'item.getElementById is not a function' error.

I've also tried a jQuery approach:

var name = item.find('#name-0')

this gets an 'item.find is not a function' error.

I don't know if item should be in {} - it's not clear to me when the braces are needed and when they are not, but if I try it with the braces I still get a '.find is not a function' error.

Can someone point out what I'm doing wrong, or even better point me in the right direction of somewhere this is documented. All I can find is very simplistic examples.

Edited to include minimal HTML example: (and amended to fix missing div tags)

<div id="container" class="position-relative col-10>

    <div id="row-0" class="row position-relative">
        <div id="name-0" class="column col-4">User 1</div>
        <div id="score-0" class="column col-2">20</div>
    </div>

    <div id="row-1" class="row position-relative">
        <div id="name-1" class="column col-4">User 2</div>
        <div id="score-1" class="column col-2">10</div>
    </div>

    <div id="row-2" class="row position-relative">
        <div id="name-2" class="column col-4 ">User 3</div>
        <div id="score-2" class="column col-2">5</div>
    </div>

</div>
Doug F
  • 13
  • 2
  • 6
  • 1
    Could you please [edit] your question to add a examlpe html? So the question includes a [mre]? Thanks. – 0stone0 Jun 14 '21 at 12:36
  • Do you have the same id for multiple elements? If not, what about `document.getElementById(#name-${index})`? – A_A Jun 14 '21 at 12:39
  • 2
    And [here](https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById) is some documentation for `document.getElementById`. Notice that you don't need the `#` in the beginning – A_A Jun 14 '21 at 12:41
  • 1
    Try `item.querySelector(`#name-${index}`)` – Tasnim Reza Jun 14 '21 at 12:42
  • item.querySelector( #name-${index} ) did the trick. Many thanks – Doug F Jun 14 '21 at 13:32
  • document.getElementById(#name-${index}) also works. Am I right in thinking though that this approach searches the whole document for the id, whereas the item.querySelector approach only searches the local node? Presumably there are potential performance differences between the two? – Doug F Jun 14 '21 at 13:35

3 Answers3

1

Since you didn't provide us with markup I assumed your markup would look somewhat like below :

HTML

<div class="parent">
  <div class="child">
      <div class="child_child">
        
      </div>
  </div>
  <div class="child">
      <div class="child_child">
        
      </div>
  </div>
</div>
<div class="parent">
  <div class="child1">
      <div class="child_child">
        
      </div>
  </div>
  <div class="child2">
      <div class="child_child">
        
      </div>
  </div>
  
</div>
<div class="parent">
  <div>
      <div class="child_child">
        
      </div>
  </div>
</div>

JS

let parent = document.querySelectorAll('.parent');
parent.forEach((child , index)=>{
    console.log(child.querySelector('.child_child') , index)
})
Sanmeet
  • 1,191
  • 1
  • 7
  • 15
0

From Why does getElementById not work on elements inside the document element?:

Container IDs should be unique, so there's no reason to find an object by ID within another container. This is why you only need document.getElementById to access any element by its ID, whereas when you are searching by class or tag name, you might want to only search within a specific container, which is why you can do x.getElementsByClassName etc.

So there's no getElementById available on the item.

Recommend using a regular document.getElementById, document.querySelector or an extra Jquery selector like so:

$('.row').each((index, item) => {

  // getElementById
  var name = document.getElementById(`name-${index}`);
  console.log(name.textContent);
  
  // Jquery
  var name2 = $(`#name-${index}`)[0];
  console.log(name2.textContent);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class='row'>
  <em id='name-0'>Name 0</em>
  <em id='name-1'>Name 1</em>
</div>

Note; the above is just an example, since OP did not yet added an example html, I've created a simple example.

0stone0
  • 34,288
  • 4
  • 39
  • 64
  • Thanks, that's a really useful insight as to why getElementById does not work for elements within the dom. I was trying to limit the scope of the search to only the local node, but I suppose that if ids are something like hashed indexes (since they are unique) it probably doesn't make any significant difference. Much appreciated. – Doug F Jun 14 '21 at 13:48
  • Yea, just like you said, since ID's must be unique on the whole document, no need to check child of an element. Glad it helped! Please consider [upvoting](https://meta.stackexchange.com/questions/173399/how-can-i-upvote-answers-and-comments) or [accepting](https://meta.stackexchange.com/q/5234/179419) any answers that might have helped you. This indicates to the wider community that you've found a solution and gives some reputation to both the answerer and yourself. – 0stone0 Jun 14 '21 at 13:52
  • I've tried upvoting, but apparently I don't yet have sufficient reputation to do so. I'll come back and upvote once I can. Thanks again – Doug F Jun 14 '21 at 14:02
0
<!DOCTYPE html>
<html>
    <body>
        <div id="row">  `This is a parent div and inside there are 4 children`
            <input />
            <input />
            <input />
            <input />
        </div>
        <button type="button" id="button">Click</button>
        <div id="result"></div>
    </body>
</html>
<script>
    var row = document.getElementById("row");     `get the element into a veriable.`
    var button = document.getElementById("button");
    var result = document.getElementById("result");
    var childNodes = row.childNodes;   `Using .childNodes you will get the children of a parent div.`

    button.addEventListener("click", () => {
    let x = 0;
    childNodes.forEach(function (item) {
         x += item;
    });
    result.innerHTML = x;
    });
</script>
  • Thanks for your response. This is slightly different from what I was trying to do (my fault for not initially including the HTML), but it gives some good examples of how I can get at those child elements. Thanks again – Doug F Jun 14 '21 at 13:59