Ali Chraghi
Ali Chraghi

Reputation: 829

Second Element Does Not Close On Click Outside

I have Problem With jQuery: In the following code, I want to close Sidenav by clicking outside when it opens The problem is that when left sidenav is opened it no longer closes because the right sidenav is an element that was created before left sidenav and i do not know how to solve this problem

$("[data-open-sidenav]").on("click", function () {
  console.log($(`#${$(this).data("open-sidenav")}`));

  if (
    $(this).data("open-sidenav").length > 0 &&
    $(`#${$(this).data("open-sidenav")}`).length
  ) {
    $(`#${$(this).data("open-sidenav")}`).animate(
      {
        left: "0",
      },
      300
    );
  }
});

$(window).on("click", function () {
  if (parseInt($(".sidenav").css("left")) === 0) {
    $(".sidenav").animate(
      {
        left: "-400px",
      },
      300,
      "linear"
    );
  }
});

$(".sidenav").on("click", function (event) {
  event.stopPropagation();
});
.sidenav {
  height: 100%;
  width: 400px;
  position: fixed;
  z-index: 1;
  top: 0;
  left: -400px;
  background-color: #fff;
  border-right: 1px solid @gray;
  overflow-x: hidden;
  transition: 0.5s;
  padding-top: 60px;
}

.sidenav li a {
  padding: 8px 8px 8px 32px;
  text-decoration: none;
  font-size: 25px;
  color: #818181;
  display: block;
  transition: 0.3s;
}

.sidenav a:hover {
  color: #f1f1f1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

    <button class="blue" data-open-sidenav="leftsn">Open Left Sidenav</button>
    <button class="blue" data-open-sidenav="rightsn">Open Right Sidenav</button>
    <div id="rightsn" class="sidenav right">
      <li>Right Sidenav</li>
    </div>
    <div id="leftsn" class="sidenav">
      <li>Left Sidenav</li>
    </div>

Upvotes: 1

Views: 47

Answers (3)

Oliver Trampleasure
Oliver Trampleasure

Reputation: 3293

The below solution works, all I have done is added a event.stopPropagation to the button clicks on the sidenav buttons, and removed the check in your hide function.

I think the issue was that the function that was checking the value of left was only checking the first incidence of the sidenav that it found - i.e. the right sidenav. Thats why it worked for the right but not the left.

Let me know if there was something else.


$("[data-open-sidenav]").on("click", function () {
  console.log($(`#${$(this).data("open-sidenav")}`));
  
  // Stop the event propogation so that the sidenav doesnt automatically close
  event.stopPropagation();

  if (
    $(this).data("open-sidenav").length > 0 &&
    $(`#${$(this).data("open-sidenav")}`).length
  ) {
    $(`#${$(this).data("open-sidenav")}`).animate(
      {
        left: "0",
      },
      300
    );
  }
});

$(".sidenav").on("click", function (event) {
  event.stopPropagation();
});

$(window).on("click", function () {

// If there is any click (that is not stopped by the event.stopPropagations)
// Hide any sidenav
    $(".sidenav").animate(
      {
        left: "-400px",
      },
      300,
      "linear"
    );
});
.sidenav {
  height: 100%;
  width: 400px;
  position: fixed;
  z-index: 1;
  top: 0;
  left: -400px;
  background-color: #fff;
  border-right: 1px solid @gray;
  overflow-x: hidden;
  transition: 0.5s;
  padding-top: 60px;
}

.sidenav li a {
  padding: 8px 8px 8px 32px;
  text-decoration: none;
  font-size: 25px;
  color: #818181;
  display: block;
  transition: 0.3s;
}

.sidenav a:hover {
  color: #f1f1f1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

    <button class="blue" data-open-sidenav="leftsn">Open Left Sidenav</button>
    <button class="blue" data-open-sidenav="rightsn">Open Right Sidenav</button>
    <div id="rightsn" class="sidenav right">
      <li>Right Sidenav</li>
    </div>
    <div id="leftsn" class="sidenav">
      <li>Left Sidenav</li>
    </div>

Upvotes: 1

Rory McCrossan
Rory McCrossan

Reputation: 337560

You have two .sidenav elements in the DOM. Accessing them by css() will return the requested property from the first one only.

As such you need to loop through them and test individually before animating, if necesssary:

$("[data-open-sidenav]").on("click", e => {
  let $target = $(`#${$(e.target).data("open-sidenav")}`);
  $target.animate({ left: 0 }, 300);
});

$(document).on("click", () => {
  $('.sidenav').each((i, el) => {
    let $el = $(el);
    if (parseInt($el.css("left")) === 0) {
      $el.animate({ left: "-400px" }, 300, "linear");
    }
  });
});

$(".sidenav").on("click", e => e.stopPropagation());
.sidenav {
  height: 100%;
  width: 400px;
  position: fixed;
  z-index: 1;
  top: 0;
  left: -400px;
  background-color: #fff;
  border-right: 1px solid @gray;
  overflow-x: hidden;
  transition: 0.5s;
  padding-top: 60px;
}

.sidenav li a {
  padding: 8px 8px 8px 32px;
  text-decoration: none;
  font-size: 25px;
  color: #818181;
  display: block;
  transition: 0.3s;
}

.sidenav a:hover {
  color: #f1f1f1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<button class="blue" data-open-sidenav="leftsn">Open Left Sidenav</button>
<button class="blue" data-open-sidenav="rightsn">Open Right Sidenav</button>
<div id="rightsn" class="sidenav right">
  <li>Right Sidenav</li>
</div>
<div id="leftsn" class="sidenav">
  <li>Left Sidenav</li>
</div>

Upvotes: 2

J. Doe
J. Doe

Reputation: 867

You could use this jQuery Plugin to archive this behaviour. Its a plugin which allows you to set Clickout-Events to Elements.

https://www.jqueryscript.net/slider/Simple-jQuery-Click-Outside-Plugin-clickout-js.html

Upvotes: 1

Related Questions