toshiomagic
toshiomagic

Reputation: 1659

Clicking on a tag to get event on sibling tag

I have the following html

<ul id="report">
  <li class="suite">
    <h1>Level 2</h1>
    <ul>
      <li class="test pass fast">
        <h2>it first</h2>
        <pre style="display: none;">
          <code>('hello').should.be.a('string');</code>
        </pre>
      </li>
    </ul>
  </li>
</ul>

I want to change the pre style from display:block to display:none when the h2 tag above it is clicked. But, I cannot for the life of me figure out how to do this. I know I need to do something along the lines of:

function changeStyle() {
    pre.style.display = 'none' == pre.style.display
    ? 'block'
    : 'none';
}

But I cannot figure out how to attach it to the h2. I've tried:

var h2 = getElementsByTagName('h2');
var pre = h2.getElementById('pre');

But that isn't right since pre is not a child of h2. I'm not sure what to do. I tried adding a variety of click event listeners to h2 and calling the changeStyle function.

Note: I would really prefer not to have to use jQuery.

Edit: Alright, so I'm not crazy. I have tried almost all of these methods before posting this question and they didn't work. There has to be something else going on here.

For example, I tried Josh Beam's method and I get: "Cannot read property 'addEventListener' of undefined" error.

I even tried wrapping it with

document.onLoad = function () {
//code
}

and it still doesn't work.

Upvotes: 0

Views: 242

Answers (4)

Josh Beam
Josh Beam

Reputation: 19772

If you want to make sure you're getting the sibling pre element, just do this (see the jsfiddle):

document.getElementsByTagName('h2')[0].addEventListener('click', function(e) {
    var pre = e.target.nextElementSibling;

    pre.style.display = pre.style.display === 'block' ? 'none' : 'block';
});

This will make sure you're not selecting any other pre elements that might be present on the page.

Upvotes: 1

Gaurang Tandon
Gaurang Tandon

Reputation: 6753

Will work for any H2 element inside ul#report

var main_ul = document.querySelector("#report");

main_ul.onclick = function(event){
  var elm = event.target;

  if(elm.tagName === "H2"){
    var pre = elm.nextElementSibling; // tada magic!
    changeStyle(pre);
  }
};

Upvotes: 1

Dhiraj
Dhiraj

Reputation: 33618

You can do something like this

var report = document.getElementById("report"); // <--- get the parent 
var h2 = report.getElementsByTagName('h2')[0];  // <--- search for h2 within parent
var pre = report.getElementsByTagName('pre')[0];// <--- search for pre within parent
h2.addEventListener('click', function(){        // <--- attach event to h2
  pre.style.display = pre.style.display === 'none' ? '' : 'none';  // <--- toggle display
});

var report = document.getElementById("report");
var h2 = report.getElementsByTagName('h2')[0];
var pre = report.getElementsByTagName('pre')[0];
h2.addEventListener('click', function() {
  pre.style.display = pre.style.display === 'none' ? '' : 'none';
});
<ul id="report">
  <li class="suite">
    <h1>Level 2</h1>
    <ul>
      <li class="test pass fast">
        <h2>it first</h2>
        <pre style="display: none;">
          <code>('hello').should.be.a('string');</code>
        </pre>
      </li>
    </ul>
  </li>
</ul>

Upvotes: 0

Zee
Zee

Reputation: 8488

You can make use of getElementsByTagName like this:

var flag = 0
document.getElementsByTagName('h2')[0].onclick = function() {
  if (flag == 1) {
    document.getElementsByTagName('pre')[0].style.display = "none";
    flag = 0;
  } else {
    document.getElementsByTagName('pre')[0].style.display = "block";
    flag = 1;
  }
}
<ul id="report">
  <li class="suite">
    <h1>Level 2</h1>
    <ul>
      <li class="test pass fast">
        <h2>it first</h2>
        <pre style="display: none;">
          <code>('hello').should.be.a('string');</code>
        </pre>
      </li>
    </ul>
  </li>
</ul>

This will also allow you to toggle the display.

Upvotes: 0

Related Questions