Mark
Mark

Reputation: 5653

How to traverse up the dom with Jquery

If I have this:

<h1>or if the title before doesn't exist then this title</h1>
<div>
  <h2>this title</h2>
  <span id="something">
    some other stuff
  </span>
  <span id="this">
    I am here
  </span>
</div>
<h2>Not this title</h2>

As I understand $(':header') should find headers. What I need it to find the first header upwards from $('#this').

Upvotes: 1

Views: 742

Answers (4)

Blender
Blender

Reputation: 298176

It's hideous, but it's a chunk that works for any level of nesting:

var $this = $('#this');

$this.add($this.parents()).map(function() {
  return $(this).prevAll(':header').eq(0);
}).get().pop();

Expanded:

$this.add(
  $this.parents()        // Adds $this's parents to the current selecor
).map(function() {       // Iterates over the selector
  return $(this)         // Returns each element's
    .prevAll(':header')  // Closest sibling header, vertically
    .eq(0);              // The first one
})
.get()                   // Gets the array from the jQuery object
.pop();                  // Trick for getting the last element

Demo: http://jsfiddle.net/xtQ2M/5/ (try deleting stuff)

Upvotes: 3

mVChr
mVChr

Reputation: 50185

This seems to be a pretty readable way to do it in case you want to change some part of your logic in the future:

var target = $('#this'),
    closestHeader = target.siblings(':header');

while (!closestHeader.length) {
    target = target.parent();
    closestHeader = target.siblings(':header');
}
closestHeader = closestHeader[0];

Note: This will get stuck if there are absolutely no headers on the page, so you might want to add a check for that first.

See demo

Upvotes: 0

Rob
Rob

Reputation: 12872

You should be able to use $(this).closest('h2'); or $(this).closest('header'); It's hard to tell with your sample code. See jQuery.closest() for more info.

Upvotes: 0

thecodeparadox
thecodeparadox

Reputation: 87073

var headers = $('#this')
        .prevAll(':header')  // all header within parent of `#this`
        .add($('#this')
                      .parent() // go to parent of `#this`
                       .prev(':header') // got the header out of `#this` parent
          );  // output [h1, h2];

DEMO

To get h1, use headers[0];

To get h2, use headers[1];

Also can use

$('#this')
         .prevAll(':header')  // all header within parent of `#this`
         .add($('#this')
                        .parent() // go to parent of `#this`
                        .prev(':header') // got the header out of `#this` parent
          ).
          .eq(0); // output: h1, if you use .eq(2) will get h2

Upvotes: 1

Related Questions