Second Element Does Not Close On Click Outside

Viewed 44

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>

3 Answers

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>

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>

Related