BlueDogRanch
BlueDogRanch

Reputation: 536

jQuery .toggle() button needs to be clicked twice

I'm trying to do two things:

  1. load the Disqus script embed.js after the "Show comments" button is clicked.
  2. Hide the disqus_thread div via the same button while changing the text in the button.

The problem is that after page load, I have to click "Show Comments" twice; the first click loads the embed.js and that should toggle disqus_thread to visible, but I have to click a second time to see the disqus_thread. (It doesn't matter than embed.js is loaded; I only want to toggle the div and hide it.)

Note: the {{ }} constructs in showComments() are , but I don't think they are the issue.

    <button id="disqus-button" onclick="showComments()">Show comments</button>
    
    <script>
    
    $( document ).ready(function() {
    $('#disqus-button').click(function(){
        $('#disqus_thread').toggle();
        $(this).text( $(this).text() == 'Show Comments' ? "Hide Comments" : "Show Comments");
    });
    });
    
    </script>
    
    <div id="disqus_thread"></div>
    
    <script>
    
    function showComments() {
        var disqus_config = function () {
        {{with .Params.disqus_identifier }}this.page.identifier = '{{ . }}';{{end}}
        {{with .Params.disqus_title }}this.page.title = '{{ . }}';{{end}}
        {{with .Params.disqus_url }}this.page.url = '{{ . | html  }}';{{end}}
        };
        var d = document, s = d.createElement('script'); s.async = true;
        s.src = '//' + "{{ .Site.DisqusShortname }}" + '.disqus.com/embed.js';
        s.setAttribute('data-timestamp', +new Date());
        (d.head || d.body).appendChild(s);
    }

</script>

Upvotes: 0

Views: 771

Answers (4)

  1. #disqus_thread should be hidden on start (as no comments are loaded)
  2. showComments() should be renamed, that's not its work, perhaps loadComments() is a better name.
  3. it should be checked if embed.js is already loaded and just execute that code once.
  4. once that is completed, is just a toggle visibility and change button text.
    <button id="disqus-button">Show Comments</button>

    <div id="disqus_thread" style="display:none">adasd</div>

    <script src="https://code.jquery.com/jquery-3.5.1.js"></script>

    <script>
        function showComments() {
            console.log('Show comments');

            //checking if embed.js is already loaded. This should just be done
            //once.
            if ($('script[src*="embed.js"]').length == 0) {
                //original code on showComments().
            }
        }

        $(document).ready(function() {
            $(document).on('click', '#disqus-button', function() {
                showComments();
                $('#disqus_thread').toggle();
                $(this).text($(this).text() == 'Hide Comments' ? "Show Comments" : "Hide Comments");
            });
        });
    </script>

Upvotes: 1

Dipen Shah
Dipen Shah

Reputation: 26085

You can add a window level variable to check if disqusJs script was added or not in click handler after toggling div that way you will toggle content as well as load script on first click.

disqusJsScriptAdded = false;

function loadDisqusJs() {
  //var disqus_config = function () {
  // {{with .Params.disqus_identifier }}this.page.identifier = '{{ . }}';{{end}}
  // {{with .Params.disqus_title }}this.page.title = '{{ . }}';{{end}}
  // {{with .Params.disqus_url }}this.page.url = '{{ . | html  }}';{{end}}
  //};
  disqusJsScriptAdded = true;
 
  var d = document,
    s = d.createElement('script');
  s.async = true;
  s.src = '//' + "{{ .Site.DisqusShortname }}" + '.disqus.com/embed.js';
  s.setAttribute('data-timestamp', +new Date());
  (d.head || d.body).appendChild(s);
}


$(document).ready(function() {
  $('#disqus-button').click(function() {
    $('#disqus_thread').toggle();
    $(this).text($(this).text() == 'Show Comments' ? "Hide Comments" : "Show Comments");
    
    if (!disqusJsScriptAdded) {
      loadDisqusJs();
    }
  });
});
#disqus_thread {
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="disqus-button">Show comments</button>
<div id="disqus_thread">
  This is content of the thread!
</div>

Upvotes: 0

RPDP
RPDP

Reputation: 1723

From what I see in the code, the issue is the <div id="disqus_thread"></div> is initially not set to be hidden.

So on first click, the call to $('#disqus_thread').toggle(); will hide the div. And the second click sets it back to visible. And I believe the button text would be out of sync with the toggle in this case.

If that is the issue, the following can fix the issue,

 $( document ).ready(function() {
    $('#disqus-button').click(function(){
       ....
    });

    $('#disqus_thread').hide(); // hide it initially when loading the page 
   });

Alternatively you can also set the style='display:none' to disqus_thread div directly.

Upvotes: 0

user14325562
user14325562

Reputation:

You can use the trigger function.

Here is the example:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

<button id="disqus-button">Show Comments</button>

<script>

    $(document).ready(function () {
        $('#disqus-button').click(function () {
            showComments();
            if ($(this).text() == 'Show Comments') {
                $(this).text("Hide Comments");
                setTimeout(() => {
                    $('#disqus-button').trigger("click");
                }, 1000);
            }
            else {
                $(this).text("Show Comments");
            }
        });
    });

</script>

<div id="disqus_thread"></div>

<script>

    function showComments() {
        console.log('show comments');
        // var disqus_config = function () {
        //     { { with.Params.disqus_identifier } } this.page.identifier = '{{ . }}'; { { end } }
        //     { { with.Params.disqus_title } } this.page.title = '{{ . }}'; { { end } }
        //     { { with.Params.disqus_url } } this.page.url = '{{ . | html  }}'; { { end } }
        // };
        // var d = document, s = d.createElement('script'); s.async = true;
        // s.src = '//' + "{{ .Site.DisqusShortname }}" + '.disqus.com/embed.js';
        // s.setAttribute('data-timestamp', +new Date());
        // (d.head || d.body).appendChild(s);
    }

</script>

Upvotes: 0

Related Questions