0

I have a hidden div which opens up on click of a link text. I need to hide the div and remove the active class from the link text when user clicks outside the div anywhere on the body.

I have used body onclick to hide the div but it is hiding the div on div click as well. I don't want to close the div only on body click, not on the div click. How can I stop the action on div click?

here is what I have tried

$('.link').click(function(e){
e.stopPropagation();
    $(this).toggleClass('active');
    $(".box").slideToggle();
});

$('body').click(function(e) {
    $(".box").hide();
        $(".link").removeClass('active');
});

DEMO

user6725932
  • 333
  • 1
  • 3
  • 16

4 Answers4

2

Try to use event.target jQuery.

event.target

$('body').click(function(event) {
  if (!$('.box').is(event.target) && $('.box').has(event.target).length === 0) {
    $('.box').slideUp();
    $('.link').removeClass('active');
  }
});
$('.link').click(function(event) {
  event.stopPropagation()
  $(this).toggleClass('active');
  $(".box").slideToggle();
});
.header {
  background: #fff;
  padding: 20px
}

body {
  height: 600px;
  font: 13px Verdana;
}

.link_div {
  position: relative
}

.link {
  display: inline-block;
  outline: none;
  padding: 10px;
  color: black;
  background: #e1e1e1;
  box-shadow: -1px -3px 3px 0px rgba(109, 109, 109, 0.2);
}

.box {
  display: none;
  background: #8bdeff;
  padding: 30px;
  position: absolute;
  top: 40px;
  left: 0
}

.active {
  background: #8bdeff
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="header">
  <div class="link_div">
    <a href="#" class="link">Open box</a>
    <div class="box">
      I am a box
    </div>
  </div>
</div>
Bhuwan
  • 16,525
  • 5
  • 34
  • 57
0

Here's what I recommend you do:

$('.link').click(function(e){
    e.stopPropagation();
    $(this).toggleClass('active');
    $(".box").slideToggle();
});

$('body').click(function(e) {
    var target = e.target;

    // Short-circuit if box is clicked OR
    // link is not active
    if ($(target).is('.box')) return;
    if (!$(".link").hasClass('active')) return

    $(".box").slideToggle();
    $(".link").removeClass('active');
});

Some things to note:

  1. e is the event passed to your eventListener when clicked, it has a target that you can check for.
  2. I'm short-circuiting when the box is the target clicked or if the link is already active
  3. I'm using the slideToggle instead of the hide because it's nicer, and since this will only trigger when the link is active, you don't have to worry about clicking outside the div and having the link toggle/open when it's closed.

Hope that helps!

JSFiddle: https://jsfiddle.net/Lm85m7nb/

Andrew Salib
  • 115
  • 1
  • 11
  • This seems like working but would you suggest the same when I have multiple divs to hide on body click? There are many click actions in my page and I need the same effect for all those. – user6725932 Jan 10 '18 at 05:55
  • JQuery's `is` works with any number of elements matched. So if you use the same class for all elements you want to hide on body click then you can check if the target is that class, if so short-circuit (which is what my code is already doing). That way you don't have to type the class name of every single element you're using etc. https://api.jquery.com/is/ – Andrew Salib Jan 10 '18 at 05:59
  • Taking it further, you can also create a loop for all links to check if each one has the class 'active', for the ones that do you can hide the box and also removeClass 'active' from the link. – Andrew Salib Jan 10 '18 at 06:06
0

You can just check if the clicked element is the class .box and do nothing if it is.

$('.link, .box').click(function(e) {    // Added .box to the click-function
  if ($(this).attr("class") == "box") { // check if the clicked element is .box
    return false;                       // do nothing like return false
  }
  e.stopPropagation();
  $(this).toggleClass('active');
  $(".box").slideToggle();
});

$('body').click(function(e) {
  $(".box").hide();
  $(".link").removeClass('active');
});
.header {
  background: #fff;
  padding: 20px
}

.link_div {
  position: relative
}

.link {
  display: inline-block;
  outline: none;
  padding: 10px;
  color: black;
  background: #e1e1e1;
  box-shadow: -1px -3px 3px 0px rgba(109, 109, 109, 0.2);
}

.box {
  display: none;
  background: #8bdeff;
  padding: 30px;
  position: absolute;
  top: 40px;
  left: 0
}

.active {
  background: #8bdeff
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="header">
  <div class="link_div">
    <a href="#" class="link">Open box</a>
    <div class="box">
      I am a box
    </div>
  </div>
</div>
Patrick Mlr
  • 2,955
  • 2
  • 16
  • 25
  • this would apply only there is no other element in the box – Dejan.S Jan 10 '18 at 07:36
  • @Dejan.S What do you mean? If you add more elements inside `.box`, it will apply. Of course it will not, if you add a new element at the same level like `.box`. – Patrick Mlr Jan 10 '18 at 12:40
-1

Hi You can use this code for add document click event for click to close in outside

$('.link').click(function(e){
  e.stopPropagation();
  e.preventDefault();
    $(this).toggleClass('active');
    $(".box").slideToggle();
});

$(document).click(function(e) {
    $(".box").hide();
        $(".link").removeClass('active');
})
Jenti Dabhi
  • 870
  • 5
  • 11