Sachin
Sachin

Reputation: 3782

How to fire an event only when a particular element is visible

I have an alert div, which appears when a user clicks on a link. Now what I want to do is to hide that div when somebody clicks outside it. It by default has a fadeoff event attached, but I want the user be able to hide that div by clicking elsewhere.

I tried putting $('body').click inside the function call but its does not work. Please help, here is my JavaScript:

 var messageDiv = $('<div id="cannotDoDiv"></div>');
      $('body').append(messageDiv);  
      
      function appendDiv(this_element,msg)
      {
        var pos = this_element.offset();  
        var width = this_element.width();  
        messageDiv.css({  
          left: (pos.left - 20) + 'px',  
          top: pos.top + 30 + 'px'  
        });  
        $('#cannotDoDiv').fadeOut();
        $('#cannotDoDiv').html(msg).show().delay(1000).fadeOut();
        $('body').click(function(){
            $('#cannotDoDiv').hide();
        });
      }
    
    $("span#selfLike").click(function(){
        appendDiv($(this),'You cannot like your own post!');
    });

When I remove:

$('body').click(function(){
    $('#cannotDoDiv').hide();
});

from my function $("span#selfLike").click works fine, otherwise it is not being fired.

Upvotes: 0

Views: 676

Answers (2)

Selvakumar Arumugam
Selvakumar Arumugam

Reputation: 79830

Edit: I think, I understood what you are trying.. see updated code below which

  1. Uses .one to bind only once and unbinds after it is done..
  2. Used on fadeIn callback so it will be binded only after the div is visible..

    //used call back function so it will be called only after it is 
    //completly visible
    $('#cannotDoDiv').html(msg).fadeIn("slow", function () {
    
         // below will be executed once and then unbind
         $(document).one('click', function(){  
           $('#cannotDoDiv').fadeOut();
        });
    
    });
    

Below is the complete code.. Updated DEMO here

$(document).ready (function () {
  var messageDiv = $('<div id="cannotDoDiv"></div>');

  $('body').append(messageDiv);  

 function appendDiv(this_element,msg)
 {
    var pos = this_element.offset();  
    var width = this_element.width();  
    messageDiv.css({  
      left: (pos.left - 20) + 'px',  
      top: pos.top + 30 + 'px'  
    });  
    $('#cannotDoDiv').hide();

    $('#cannotDoDiv').html(msg).fadeIn("slow", function () {

         $(document).one('click', function(){
           $('#cannotDoDiv').fadeOut();
        });

    });    

    $('#cannotDoDiv').one('click', function(){
       $('#cannotDoDiv').fadeOut();
    });
 }

$("span#selfLike").click(function(event){
    appendDiv($(this),'You cannot like your own post!');
    event.stopPropagation();
  });

 });

Note: This also closes when you click on the $('#cannotDoDiv') div. Add an click listener and stopPropogation if you don't want that to happen.

Try $(document).click(function(){ instead of body.

Upvotes: 1

Jasper
Jasper

Reputation: 75993

You can stop the propagation of the click event if it is fired on the div element so it doesn't reach the document, then bind a click event handler to the document element that hides the div:

$('#cannotDoDiv').on('click', function (event) {
    event.stopPropagation();
});
$(document).on('click', function () {
    $('#cannotDoDiv').hide();//you can now hide the div element because it was not clicked on but a click event fired
});

Note that .on() is new in jQuery 1.7 and in this case is the same as using .bind().

You could also un-bind the click event handler from the document once it fires to stop listening for the event if it isn't necessary to do so:

$(document).on('click.cannotDoDiv', function () {
    $('#cannotDoDiv').hide();//you can now hide the div element because it was not clicked on but a click event fired
    $(this).off('click.cannotDoDiv');
});

Since I used a namespace for the event this will not remove any other event handlers attached to the document element. Also, .off() is new in jQuery 1.7 and is the same in this case as .unbind().

Upvotes: 0

Related Questions