vcapra1
vcapra1

Reputation: 2025

jQuery parent() function returns empty

I have the following html (simplified to basic setup):

<div class="findme">
  <table>
    <tr>
      <td>
        <img id="image" src="image.png" onclick="findTheDiv(event)" />
      </td>
    </tr>
  </table>
</div>

When I click on the image, the findTheDiv(event) function runs, which looks like this:

function findTheDiv(event) {
  var elem = $(event.toElement);
  var found = false;
  // stop the loop if the top-level element is reached (html)
  while (!$(elem).is("html")) {
    if ($(elem).is("div.findme")) {
      found = true;
      break;
    }
    elem = $(elem).parent();
    console.log(elem);
  }
}

This runs, and for each iteration of the while loop, I log the new elem, which is the previous element's parent, to the console. This is the result I get:

[<img id="image" src="image.png" onclick="findTheDiv(event)">]
[<td>]
[<tr>]
[<table>]
[]

When the table is reached, it apparently has no parent, even though it clearly does, which is the div. To further test this, I used the console to execute this:

$("table").parent();

And it returned a blank array

[]

Why is jQuery saying the table does not have a parent, since all elements except for the <html> have parents?

Upvotes: 4

Views: 3789

Answers (2)

Mehdi
Mehdi

Reputation: 7403

the jQuery closest function already provides the feature you are looking for, no need to reinvent the wheel:

function findTheDiv(e) {
  var res = $(elem).closest('div.findme')
  if (res. length) {
    console.log('found it', res)
    return true
  }
  console.log('the image is not inside a `div.findme`')
  return false
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="findme">
  <table>
    <tr>
      <td>
        <img id="image" src="image.png" onclick="findTheDiv(this)" />
      </td>
    </tr>
  </table>
</div>

Upvotes: 2

TaoPR
TaoPR

Reputation: 6052

I changed your code a little and it works fine. Instead of using an event object as an argument, I just pass this to reference the object which fires the event directly. This serves the same purpose.

function findTheDiv(elem) {
  //var elem = $(event.toElement);
  var found = false;
  // stop the loop if the top-level element is reached (html)
  while (!$(elem).is("html")) {
    if ($(elem).is("div.findme")) {
      found = true;
      break;
    }
    elem = $(elem).parent();
    console.log(elem);
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="findme">
  <table>
    <tr>
      <td>
        <img id="image" src="image.png" onclick="findTheDiv(this)" />
      </td>
    </tr>
  </table>
</div>

Run the snippet, have your JavaScript console open and see what it logs.

Upvotes: 2

Related Questions