Tim Tim - 1 month ago 9
jQuery Question

jQuery not changing text in tag

I'm trying to use jQuery to change the text of a tag when clicked. From other questions on stack overflow this should be correct, but for some reason it's not working.

The text is a "Read more" line which triggers the show/hide of a div block.

The show/hide part works, but the text of the "Read more" should switch to "Close" as appropriate. Any suggestions?

This is the javascript, loaded in the header (jquery is also loaded by this time):

</script>
$(document).ready(function() {

$('.faq_question').click(function() {

if ($(this).parent().is('.open')){
$(this).closest('.faq').find('.faq_answer_container').animate({'height':'0'},500);
$(this).closest('.faq').removeClass('open');
$(this).closest('.faq_toggle h4').text('Read More');

}else{
var newHeight =$(this).closest('.faq').find('.faq_answer').height() +'px';
$(this).closest('.faq').find('.faq_answer_container').animate({'height':newHeight},500);
$(this).closest('.faq').addClass('open');

$(this).closest('.faq_toggle h4').text('Close');

}

});

});
</script>


This is the CSS:

.faq_question {
margin: 0px;
padding: 0px 0px 5px 0px;
display: inline-block;
cursor: pointer;
font-weight: bold;
}

.faq_answer_container {
height: 0px;
overflow: hidden;
padding: 0px;
}

.faq_toggle {
color: #00adef;
}


And finally, the markup:

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

<div class="std">​

<div class="faq_container">
<div class="faq">
<div class="faq_answer_container">
<div class="faq_answer">​
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
</div>
</div>
<div class="faq_question"><h4 class="faq_toggle"><strong>Read more</strong></h4></div>
</div>
</div>​

</div>​


As noted above, the show/hide works, but the "Read more" text doesn't switch to "Close".

Answer

In your code, this refers to the element you clicked on, which is .faq_question.

Since .faq_toggle is a child of .faq_quesetion, you can't traverse from .faq_question to .faq_toggle by using closest().

closest(): For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree.

I suggest using find() or, as in my example below, a context selector:

$(document).ready(function() {

  $('.faq_question').click(function() {

    if ($(this).parent().is('.open')) {
      $(this).closest('.faq').find('.faq_answer_container').animate({
        'height': '0'
      }, 500);
      $(this).closest('.faq').removeClass('open');
      $('.faq_toggle', this).text('Read More');

    } else {
      var newHeight = $(this).closest('.faq').find('.faq_answer').height() + 'px';
      $(this).closest('.faq').find('.faq_answer_container').animate({
        'height': newHeight
      }, 500);
      $(this).closest('.faq').addClass('open');

      $('.faq_toggle', this).text('Close');

    }

  });

});
.faq_question {
  margin: 0px;
  padding: 0px 0px 5px 0px;
  display: inline-block;
  cursor: pointer;
  font-weight: bold;
}
.faq_answer_container {
  height: 0px;
  overflow: hidden;
  padding: 0px;
}
.faq_toggle {
  color: #00adef;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="std">

  <div class="faq_container">
    <div class="faq">
      <div class="faq_answer_container">
        <div class="faq_answer">
          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
        </div>
      </div>
      <div class="faq_question">
        <h4 class="faq_toggle"><strong>Read more</strong></h4>
      </div>
    </div>
  </div>

</div>


Also, as mentioned by mospans, a .faq_toggle h4 selector would select an <h4> element that is a child of .faq_toggle. Instead, you want to select an <h4> element with the class .faq_toggle:

$('h4.faq_toggle')

or just

$('.faq_toggle')