Elated Coder
Elated Coder

Reputation: 322

Read more button won't work on clicking it once but many times

This is a small issue but I am stuck. I have a read more button for each post on a page which won't work on clicking once. It works on clicking it as many times as the number of posts on a page.

Here is my code:

$(function(){
    var maxLength = 500;
    $(".content-wrapper").each(function(){
        var myStr = $(this).html();
        if($.trim(myStr).length > maxLength){
            var newStr = myStr.substring(0, maxLength);
            var removedStr = myStr.substring(maxLength, $.trim(myStr).length);
            $(this).empty().html(newStr);
            $(this).append(' <a href="javascript:void(0);" class="read-more">read more...</a>');
            $(this).append('<span class="more-text">' + removedStr + '</span>');
        }
    });
   
});

 $(".read-more").click(function(event){
       $(this).hide();
        $(this).siblings(".more-text").show();
        event.preventDefault();
    });
            .content-wrapper .more-text{
                display: none;
            }
       
<div class="content-wrapper">
            <span style="color:green"><h4>{{TITLE}}</h4> </span>
            {{POST}}
        </div>
       

Upvotes: 0

Views: 60

Answers (2)

Jay Blanchard
Jay Blanchard

Reputation: 34416

jQuery is only aware of the elements in the page at the time it runs, so new elements added to the DOM are unrecognized by jQuery. To combat the problem use event delegation, bubbling events from newly added items up to a point in the DOM which was there when jQuery ran on page load. Many people use document as the place to catch the bubbled event, but it isn't necessary to go all the way up the DOM tree. Ideally you should delegate to the nearest parent existing at the time of page load.

$(document).on('click','read-more', function(event){
    $(this).hide();
    $(this).siblings(".more-text").show();
    event.preventDefault();
});

You may be able to delegate to $('content-wrapper')

EDIT: You were not properly hiding the extra content. Here is the whole code:

$(function() {

    var maxLength = 500;
    $(".content-wrapper").each(function() {
      var myStr = $(this).html();

      if ($.trim(myStr).length > maxLength) {
        var newStr = myStr.substring(0, maxLength);

        var removedStr = myStr.substring(maxLength, $.trim(myStr).length);
        $(this).empty().html(newStr);
        $(this).append(' <a href="javascript:void(0);" class="read-more">read more...</a>');
        $(this).append('<span class="more-text">' + removedStr + '</span>');
        $('.more-text').hide(); // <-- line added
      }
    });

    $('.content-wrapper').on('click', '.read-more', function(event) {
       $(this).hide();
       $(this).siblings(".more-text").show();
       event.preventDefault();
    });
})

EXAMPLE

Upvotes: 3

Ryan Wilson
Ryan Wilson

Reputation: 10765

You can do as Jay Blanchard said or you can just attach the click event listeners for read-more className elements after appending like so, in your original code you were attaching the click events to elements with className read-more immediately when the script file is loaded, they do not exist at that time, if you move the attaching of the click events to the elements with className read-more inside of the document.ready after appending them they will work:

$(function(){
    var maxLength = 500;
    $(".content-wrapper").each(function(){
        var myStr = $(this).html();
        if($.trim(myStr).length > maxLength){
            var newStr = myStr.substring(0, maxLength);
            var removedStr = myStr.substring(maxLength, $.trim(myStr).length);
            $(this).empty().html(newStr);
            $(this).append(' <a href="javascript:void(0);" class="read-more">read more...</a>');
            $(this).append('<span class="more-text">' + removedStr + '</span>');
        }
    });

    //Now that the read-more className elements exist in the DOM from .append
    //Attach the click event handlers
    $(".read-more").click(function(event){
       $(this).hide();
        $(this).siblings(".more-text").show();
        event.preventDefault();
    });



});

Upvotes: 0

Related Questions