views:

128

answers:

4

Hi,

Below is html

<div class="radio_tab"><span>Ad View</span>
    <ul>
     <li>Ad View</li>
     <li>Page View</li>
    </ul>
</div>

My javascript is

$("div").not('.radio_tab').click(function(){
     alert('hi');

});

and also i tried

$("div:not(.radio_tab)").click(function(){
     alert('hi');

});

I am showing dropdown on click of span and it will hide on clicking on span/ul. But problem is, i want to hide dropdown onclicking outside div.radio_tab.

I appreciate all your comments

A: 

Both of those selectors will find all divs that do not have the class radio_tab, and apply click handlers to them. That's probably amazingly inefficient, on top of not being what you want to do. The thing it seems like you're trying to do ($("*:not('div.radio_tab')")) would be even worse.

One alternate approach might be to apply a click handler to the body of the document, and test the event's target to see whether it's div.radio_tab, or one of its children. If not, then hide the div and unbind the event handler. Something along these lines (code written here, and not tested!):

// attach the event handler to the body, where it will hear about
// any clicks that don't have default behavior (like links);
// use a namespaced event, so that it can be easily removed
$(document.body).bind("click.radio_tab",function(evt){
  // make sure the click is outside the div in question
  if( $(evt.target).closest("div.radio_tab").length === 0 ) {
    // hide the div, or whatever else needs to be done
    $("div.radio_tab").hide();
    // unbind the event, since it's no longer needed
    $(this).unbind("click.radio_tab");
  }
});
Sixten Otto
thanks for your reply. Can you elaborate more. I tried this $('*').click(function(){ if(!$(this).parents('div:eq(0)').hasClass("radio_tab")) alert('hi'); });Problem in this is, it travels till root tag.
vinay
That right there is a terrible idea: you've attached an event handler to *every element in your document*. What I was proposing was taking advantage of the bubbling of events to add a single event handler to the body. I'll edit my answer in a moment.
Sixten Otto
Thanks Sixten, really cool idea.
vinay
A: 

since you are checking the class use hasClass instead to get the boolean answer:

($("div").hasClass("radio_tab"))
curtisk
A: 

Here is how I handle a similar situation:

jQuery('div').click(function () {
    if (! (jQuery(this).hasClass('radio_tab'))) {
        /* do something */
    };

Here is exactly how I handle this on my site www.ipreferjim.com:

jQuery('div.nav_link').click(function () {
    if (! (jQuery(this).hasClass('no_select'))) {
        jQuery('div.nav_link').not(this).find('div.top_level').removeClass('nav_selected');
        jQuery(this).find('div.top_level').addClass('nav_selected');
    };
});
/* end div.nav_link .click */

jQuery('div.nav_link').hover(function () {
    jQuery(this).find('div.top_level').fadeOut(100);
    jQuery(this).find('div.top_level').fadeIn(300);
    /* Show Sub-menu */
    jQuery(this).find('.sub_level').show();
},
function () {
    jQuery(this).find('.sub_level').hide();
});
/* end 'div.nav_link' .hover */

jQuery('div.sub_level a.dialog_link').click(function () {
    if (jQuery(this).hasClass('get_json')) {
        var json_link = 'retrieve.php?type=example&short_name=' + jQuery(this).attr('id') + '&format=json';
        jQuery.getJSON(json_link, function (json) {
            jQuery('.ui-dialog-title').text(json.title);
            jQuery('.ui-dialog-content').html(json.html);
        });

        jQuery('#dialog').dialog('open');

        return false;
    };
    /* end if */
});
/* end div.sub_level a.dialog_link .click */

Then, my links are set up using div elements with nested unordered lists.

<div class="nav_link"> 
 <div class="top_level">Code</div><!-- end top_level --> 
   <div class="sub_level ui-corner-bottom"> 
     <ul id="links"> 
       <li><a href="?contentlink=assignments.php" id="assignments.php" class="navigation underline" onclick="javascript:showContent(this,'assignments.php')">Assignments</a>
       </li> 
       <li>Snippets</li> 
     </ul> 
    </div><!-- end sub_level --> 
  </div><!-- end nav_link -->

It seems to be a very similar problem.

Jim Schubert
Thanks for your feedback. problem is i can't $('div'), because tag can be other than Div.
vinay
I edited my comment to show how I do this. You can add the same class to both your div and span elements if you want them to have the same behavior.
Jim Schubert
A: 

The problem with using the not selector in this case is if you have your radio_tab wrapped with another div it will stop working completely because the wrapping div doesn't have the radio_tab class... so either make sure there is no wrapping div and use Jim's answer or try something similar to this (but this answer could be way out in left field)

HTML

<div class="wrapper">
 <div class="not_radio_tab"><input type="text" readonly value="Not Ad View" />
  <ul>
   <li>Not Ad View</li>
   <li>Not Page View</li>
  </ul>
 </div>
 <div class="radio_tab"><input type="text" readonly value="Ad View" />
  <ul>
   <li>Ad View</li>
   <li>Page View</li>
  </ul>
 </div>
</div>

Script

$(document).ready(function(){
 $('.radio_tab input')
  .focus(function() {
   $(this).parent().find('ul').css('background-color','#fc0')
  })
  .blur(function() {
   $(this).parent().find('ul').css('background-color','#222')
  });
})
fudgey