user3052886 user3052886 - 1 month ago 5
Javascript Question

can't get the toggle function to work

I am new to jQuery and am experimenting with some plugins. I found one called jQuery Balloon. When I add my script and run the code the bubble pops up but won't go away.

Here is my code:

<script type="text/javascript" src="/js/jquery.js"></script>
<script type="text/javascript" src="/js/jquery.balloon.min.js"></script>


Here is my jQuery code. I omitted the
document.ready
because I have that at the top of my document already.

$("a").click(function(event){
$(this).showBalloon().toggle();
event.preventDefault();


How do I get the balloon popup when the user clicks the link and have it go away when they click away from it?

Answer
$('a').on('click', ( function balloonState(){
  var state = true;

  return function(ev) {
      var $this = $(this);

      if (state) {
          $this.showBalloon();
      } else {
          $this.hideBalloon();
      }

      state = !state;

      ev.preventDefault();
  } 
}() ) );

Alnitak's answer is functionally perfect as far as the question goes, but you can achieve the same with simple native closures (without having to use $.fn.data), the advantages being:

  • Saving on code execution by avoiding jQuery's DOM-associated data binding and only declaring state once
  • Avoid needlessly saving state in the DOM, where other code can tamper with it

EDIT: As Alnitak pointed out in the comments, an immediately invoked closure would only create one state variable for all <a>s. Assuming that's not what's desired, we can use jQuery's each to create a closure for each <a>:

$('a').each( function balloonState(){
  var state = true;
  var $this = $( this );

  $this.on( 'click', function(ev) {
      if (state) {
          $this.showBalloon();
      } else {
          $this.hideBalloon();
      }

      state = !state;

      ev.preventDefault();
  } );
} );

EDIT 2: The method above has the caveat that it will create a new function for each link on the page at runtime, which is very wasteful in terms of memory management and speedy initialization. The plugin homepage uses the old jQuery toggle method to get around the problem of when to execute hideBalloon and showBalloon, but this was deprecated in jQuery 1.9. Overall I'd recommend using Alnitak's method.

Comments