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");
}
});
});