Home > Mobile >  jQuery on click only works once
jQuery on click only works once

Time:10-24

I have a script that enhances a button so the page can return to top and then open a sidebar. It contains script that allows a button 'reset' as it is an on click script. The reset part only works once after a page refresh and will not work after that. The bottom part 'toggleClick(true);' is the part that only works once. How can I make it so the reset part works consistently?

jQuery(document).ready(function($) {
  function toggleClick(on) {
    if (on) {
      $('.button').on('click', function() {
        setTimeout(function() {
          $('.sidebaropen')[0].click()
        }, 210);
        $("html, body").animate({
          scrollTop: 0
        }, "fast");
        toggleClick(false);
        console.log('clicked');
      });

    } else {
      $('.button').off('click');
    }

  }
  toggleClick(true);

  $('.button').on('click', function() {
    console.log('Reset done');
    setTimeout(function() {
      toggleClick(true);
    }, 210);
  });
});

CodePudding user response:

You're calling toggleClick(false) which removes the click handler after the button is clicked. It is equivalent to using $('.button').one(...).

Why remove the click handler at all? You could just hide the button when the page is already scrolled to the top. Here's some code that I've used in the past. It's not pretty, but it works:

// scrollStopped function modified from accepted answer at 
// https://stackoverflow.com/questions/14035083/jquery-bind-event-on-scroll-stop/14035162#14035162
$.fn.scrollStopped = function (callback) {
  var $this = $(this),
    self = this;
  $this.scroll(function () {
    if ($this.data('scrollTimeout')) {
      clearTimeout($this.data('scrollTimeout'));
    }
    $this.data('scrollTimeout', setTimeout(callback, 250, self));
  });
};

// If the menu is out of view (in my case, at 215px), show the button
// fadeIn/fadeOut not necessary; you could just use show/hide
$(window).scrollStopped(function () {
  if ($(this).scrollTop() > 215) {
    $('.button').fadeIn('fast');
  } else {
    $('.button').fadeOut('fast');
  }
});

// button click scrolls back to the top of the page
$('.button').click(function () {
  $('html, body').animate({
    scrollTop: 0
  });
  // You can add your .sidebaropen click here
});

CodePudding user response:

JQuery.off removes all event listeners for a given element. Therefore, your second event for Reset done is getting removed as well from the first event callback. Honestly, the best way to fix this is to just use vanilla JavaScript as you cannot remove a specific event instance with JQuery:

const $btn = document.querySelector(".button");

const handleClick = () => {
  $("html, body").animate({
    scrollTop: 0
  }, "fast");
  toggleClick(false);
};

function toggleClick(state) {
  if (state) {  
    $btn.addEventListener('click', handleClick);
  } else {
    $btn.removeEventListener('click', handleClick);
  }
}

toggleClick(true);

$('.button').on('click', function() {
  setTimeout(function() {
    toggleClick(true);
  }, 210);
});
div {
  min-height: 200vh;
}

.button {
  position: fixed;
  right: 1rem;
  bottom: 1rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>So contentful</div>
<button class="button">Go Up</button>
<aside class="sidebar">Awesome sidebar</aside>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

Easy way to do this. Please read the comments for more clarification.

$(document).ready(function(){
   $('.button').on('click', function() {
       var isClicked = $(this).attr("isClicked"); // get the attr value from the button it not found in first time
if(!isClicked){ // check if isClicked not found
        setTimeout(function() {
          $('.sidebaropen')[0].click()
        }, 210);
        $("html, body").animate({
          scrollTop: 0
        }, "fast");
$(this).attr("isClicked",1); // when you cliked the button this will set the isClcked attribute to your button
       }
 });
});

Thanks

  • Related