Home > Software design >  How to better write using jquery to click on the periphery to close the pop-up window
How to better write using jquery to click on the periphery to close the pop-up window

Time:07-11

I want to realize that a window can appear when the button is clicked, and when the click is outside the window, the window can be closed, but at present I judge it by e.target.className, but I think this way of writing is not ideal because if it is inside the window If there are a lot of objects, I seem to have to write more e.target.className to complete the requirements, so I want to find a better and more professional way of writing!

In addition, I hope that I can click the tool button repeatedly to close and open the window, but I don't know how to write it. I tried to use the toggle method but still can't achieve the effect. I hope I can get your help, thank you.

$(".tool").on("click", function (e) {
  $(document).on("click", function (e) {
    if (
      e.target.className == "delet_wrap" ||
      e.target.className == "consider" ||
      e.target.className == "confirm" ||
      e.target.className == "btn_group" ||
      e.target.className == "tool" ||
      e.target.className == "txt"
    ) {
      $(".delet_wrap").css("display", "inline-block");
    } else {
      $(".delet_wrap").css("display", "none");
    }
  });
});
body {
  width: 100%;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}

.tool {
  position: relative;
  text-decoration: none;
  background-color: yellow;
  border: 1px solid #222;
  border-radius: 6px;
  padding: 10px;
  color: #222;
}
.tool .delet_wrap {
  padding: 20px;
  position: absolute;
  bottom: -90px;
  left: 10px;
  background-color: #ccc;
  border: 1px solid #222;
  display: none;
}
.tool .delet_wrap p {
  text-align: center;
}
.tool .delet_wrap .btn_group {
  display: flex;
  white-space: nowrap;
  margin-top: 10px;
}
.tool .delet_wrap .btn_group .consider {
  background-color: #fff;
  border: 1px solid #222;
  margin-right: 10px;
}
.tool .delet_wrap .btn_group .confirm {
  text-decoration: none;
  border: 1px solid #222;
  margin-left: 10px;
  background-color: #222;
  color: #fff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a href="javascript:;" >tool
  <div >
    <p >Are you sure you want to remove?</p>
    <div >
      <button >consider</button>
      <button >confirm</button> 
    </div>
  </div>
</a>

CodePudding user response:

First of all, you don't need any bloatware-jquery for this, you can use combination of element.matches and element.closest to check clicked element:

document.querySelectorAll(".tool").forEach(el => el.addEventListener("click", function (e) {
  let node = e.target;
 
  //check if clicked any buttons inside the popup
  if (node.matches("button.consider"))
  {
    console.log(node.textContent);
    return;
  }
  
  if (node.matches("button.confirm"))
  {
    console.log(node.textContent);
    return;
  }
  
  //if popup element element exists as a child, the main button clicked
  if (node = node.querySelector(".delet_wrap"))
  {
    //if popup already opened do nothing
    if(node.style.display == "inline-block")
      return;

    document.body.click(); //close other popups

    //show popup
    node.style.display = "inline-block";
    //create onClick function so we can remove listener later
    const onClick = e =>
    {
      //hide popup
      node.style.display = "none";
      //remove listener
      document.removeEventListener("click", onClick);
    };
    //add listener
    document.addEventListener("click", onClick);
  }

  // stop propagation to prevent trigger document click
  e.stopPropagation();

}));
body {
  width: 100%;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}

.tool {
  position: relative;
  text-decoration: none;
  background-color: yellow;
  border: 1px solid #222;
  border-radius: 6px;
  padding: 10px;
  color: #222;
}
.tool .delet_wrap {
  padding: 20px;
  position: absolute;
  bottom: -90px;
  left: 10px;
  background-color: #ccc;
  border: 1px solid #222;
  display: none;
}
.tool .delet_wrap p {
  text-align: center;
}
.tool .delet_wrap .btn_group {
  display: flex;
  white-space: nowrap;
  margin-top: 10px;
}
.tool .delet_wrap .btn_group .consider {
  background-color: #fff;
  border: 1px solid #222;
  margin-right: 10px;
}
.tool .delet_wrap .btn_group .confirm {
  text-decoration: none;
  border: 1px solid #222;
  margin-left: 10px;
  background-color: #222;
  color: #fff;
}
<a href="javascript:;" >tool
  <div >
    <p >Are you sure you want to remove?</p>
    <div >
      <button >consider</button>
      <button >confirm</button> 
    </div>
  </div>
</a>

<a href="javascript:;" >tool 2
  <div >
    <p >Are you sure you want to remove? 2</p>
    <div >
      <button >consider 2</button>
      <button >confirm 2</button> 
    </div>
  </div>
</a>

CodePudding user response:

You can use an array to hold these, then use includes to determine:

const className = ['delet_wrap', 'consider', 'confirm', 'btn_group', 'tool', 'txt']

$(".tool").on("click", function (e) {
  $(document).on("click", function (e) {
    if (className.includes(e.target.className)) {
      $(".delet_wrap").css("display", "inline-block");
    } else {
      $(".delet_wrap").css("display", "none");
    }
  });
});

  • Related