Find next cell contained in sibling string using querySelector

I am trying to use querySelector

to find the first cell in a NEXT row of a table. So, starting at ROW 1, find the next TR element and then find the first TD child inside that TR element.

However, when I write a CSS selector, it returns null

.

CSS syntax syntax:

"tr.row ~ tr td"

      

Here's a complete working example:

<!DOCTYPE html>
<html>
<head>

    <script>
        function findRow()
        {
            var row1 = document.querySelector("tr.row");
            var targetCell = row1.querySelector("tr.row ~ tr td");
            alert(targetCell);
        }
    </script>

</head>

<body>

    <table>
        <tr class = "row">
            <td class = "cell"></td>
        </tr>
        <tr class = "row">
            <td class = "cell"></td>
        </tr>
    </table>

    <script>
        findRow();
    </script>

</body>
</html>

      

So the selector ".row1

successfully gives me a TR element with id row1

.

However, the second selector ".row1 ~ tr td"

returns null

.

Now if instead of calling querySelector

with an element, TR

I call document.querySelector

, it works. I can even call row1.parentNode.querySelector

and then it works. This indicates that the actual item being called querySelector

is not in the item set to search.

Unfortunately this is not a solution. This is just a simplified example: in my actual use case, I cannot call querySelector

from the parent element above row1

, because then I will lose the context I am in (in my real use case I have a lot of dynamically generated strings, so if I call document.querySelector

or even row1.parentNode.querySelector

, I will lose my context).

I realize I can just do this with simple DOM looping workarounds, but I'm trying to get used to using it querySelector

here as it is obviously better for the future. (Also, I am not using jQuery here.) I also suspect the selector :scope

will help here, but unfortunately not yet widespread.

So is it possible to do what I want using querySelector

?

+3


source to share


3 answers


Difficult to use querySelector

. The problem with element.querySelector is that these are leaf nodes only. Better to use something like

var targetCell = row1.nextElementSibling.cells[0];

      

var row1 = document.querySelector("tr.row"),
    targetCell = row1.nextElementSibling.cells[0];
alert(targetCell);
      

<table>
  <tr class="row">
    <td class="cell"></td>
  </tr>
  <tr class="row">
    <td class="cell"></td>
  </tr>
</table>
      

Run codeHide result




If you really want to use it, you can use the :nth-child(k)

parent to reference the k

th element .

var parent = row1.parentElement,
    index = [].slice.call(parent.children).indexOf(row1) + 1,
    targetCell = parent.querySelector(":nth-child("+index+") ~ tr td");

      

var row1 = document.querySelector("tr.row"),
    parent = row1.parentElement,
    index = [].slice.call(parent.children).indexOf(row1) + 1,
    targetCell = parent.querySelector(":nth-child("+index+") ~ tr td");
alert(targetCell);
      

<table>
  <tr class="row">
    <td class="cell"></td>
  </tr>
  <tr class="row">
    <td class="cell"></td>
  </tr>
</table>
      

Run codeHide result


+4


source


Yes, you can target #cell2

on querySelector

, but you will need to do this with document.querySelector

, and do not element.querySelector

.

The problem with element.querySelector

is that these are only child nodes of targets, hence sibling nodes and their children. From MDN :

Returns the first element that is a descendant of the element it is invoked on that matches the specified selector group.



Here's a script showing the change: http://jsfiddle.net/usho2t63/

var targetCell = document.querySelector("#row1 ~ tr td");

      

+1


source


Since a CSS selector cannot travel to parents, your best approach would be to use DOM methods, as Oriol already answered.

Alternatively, using only querySelector

if you make sure to give each element an ID, you should do something like this:

document.querySelector("#" + row1.getAttribute("id") + " ~ tr td");

      

to make sure you always target the reference string

0


source







All Articles