admin管理员组文章数量:1277875
I am having troubles with getting a popup to e up at the exact location of my mouse click. I want to be able to click a DIV (that is inside a table cell) and for a popup to show up whenever this div is clicked.
Right now I have the popup working, however no matter what I try the popup DIV is half way down the page.
HTML
<ul class="customdropdown" style="display:none;" id="xxx<?php echo $fetch['unit_no']; ?>" role="menu" aria-labelledby="menuitems">
<li role="presentation"><a role="menuitem" tabindex="-1" href="#"</i>Link 1</a></li>
<li role="presentation"><a role="menuitem" tabindex="-1" href="#"</i>Link 2</a></li>
</ul>
JQUERY
$(document).ready(function () {
$('#myDiv<?php echo $fetch['unit_no']; ?>').click(function (e) {
var myDiv = document.getElementById('myDiv<?php echo $fetch['unit_no']; ?>');
var leftx = e.pageX-myDiv.offsetLeft;
var topy = e.pageY-myDiv.offsetTop;
$("#xxx<?php echo $fetch['unit_no']; ?>")
.css({
position: 'absolute',
left: leftx,
top: topy,
display: 'block'
})
});
});
Screenshot of what is happening below:
Is this to do with the positioning of the DIV?
I am having troubles with getting a popup to e up at the exact location of my mouse click. I want to be able to click a DIV (that is inside a table cell) and for a popup to show up whenever this div is clicked.
Right now I have the popup working, however no matter what I try the popup DIV is half way down the page.
HTML
<ul class="customdropdown" style="display:none;" id="xxx<?php echo $fetch['unit_no']; ?>" role="menu" aria-labelledby="menuitems">
<li role="presentation"><a role="menuitem" tabindex="-1" href="#"</i>Link 1</a></li>
<li role="presentation"><a role="menuitem" tabindex="-1" href="#"</i>Link 2</a></li>
</ul>
JQUERY
$(document).ready(function () {
$('#myDiv<?php echo $fetch['unit_no']; ?>').click(function (e) {
var myDiv = document.getElementById('myDiv<?php echo $fetch['unit_no']; ?>');
var leftx = e.pageX-myDiv.offsetLeft;
var topy = e.pageY-myDiv.offsetTop;
$("#xxx<?php echo $fetch['unit_no']; ?>")
.css({
position: 'absolute',
left: leftx,
top: topy,
display: 'block'
})
});
});
Screenshot of what is happening below:
Is this to do with the positioning of the DIV?
Share Improve this question edited Jan 13, 2022 at 4:17 Roko C. Buljan 207k41 gold badges327 silver badges337 bronze badges asked Jan 13, 2022 at 2:42 GessetGesset 631 gold badge1 silver badge7 bronze badges 2-
Why do you have unclosed
<a
elements? – Roko C. Buljan Commented Jan 13, 2022 at 3:08 - I think you should accept the answer below. – WinEunuuchs2Unix Commented Nov 6, 2022 at 21:23
1 Answer
Reset to default 10It depends whether your popup (tooltip) is position absolute
or fixed
and the parent has any position
other than static
set, and if the popup is inside the wrapper or not; or is a direct child of body
.
Three examples ahead:
- Absolute popup as child of a non-static parent (has Pros and Cons)
- Fixed popup (has Pros and Cons)
- Absolute popup as immediate child of document
<body>
(Best)
1. Move absolute child to X,Y coordinates within the parent
Case: position: absolute;
popup inside a position: relative;
parent.
- If the parent has scrollbars (
overflow
value other thanvisible
)
X = Event.pageX + Parent.scrollLeft - Parent.offsetLeft
Y = Event.pageY + Parent.scrollTop - Parent.offsetTop
- If the Parent has no scrollbars (Don't use this!):
// !! Bad practice !!
X = Event.pageX - Parent.offsetLeft
Y = Event.pageY - Parent.offsetTop
Example:
const el = (sel, par) => (par||document).querySelector(sel);
const elArea = el("#area");
const elPopup = el("#popup");
const showPopup = (evt) => {
const elBtn = evt.currentTarget;
Object.assign(elPopup.style, {
left: `${evt.pageX + elBtn.scrollLeft - elBtn.offsetLeft}px`,
top: `${evt.pageY + elBtn.scrollTop - elBtn.offsetTop}px`,
display: `block`,
});
};
elArea.addEventListener("click", showPopup);
body {
height: 300vh; /* Just to force some scrollbars */
}
#area {
position: relative; /* this is needed! */
height: 150px;
background: #eee;
margin: 40px;
}
#popup {
position: absolute;
height: 30px;
background: gold;
display: none;
}
<div id="area">
Click here to shop popup, and scroll the window
<div id="popup">Popup</div>
</div>
Pros:
- Even if the page is scrolled, the popup stays still inside the wrapping element
Cons:
- Additional code is needed to prevent the popup move if it was the actual Event
target
- to allow inner content to be interacted with and the popup not to move. - The popup needs to be child of a specific parent Element, which leads to poor code reusability. PS: A solution would be using:
SomeClickedElement.append(EL_popup)
. - The wrapping parent element (
#area
) needs aposition
set (other thanstatic
), i.e:position: relative;
2. Move fixed element to X,Y coordinates
Case: position: fixed;
popup outside (or inside) of parent, but usually as child of <body>
.
X = Event.clientX
Y = Event.clientY
Example:
const el = (sel, par) => (par||document).querySelector(sel);
const elArea = el("#area");
const elPopup = el("#popup");
const showPopup = (evt) => {
Object.assign(elPopup.style, {
left: `${evt.clientX}px`,
top: `${evt.clientY}px`,
display: `block`,
});
};
elArea.addEventListener("click", showPopup);
body {
height: 300vh; /* Just to force some scrollbars */
}
#area {
/* position: relative; /* not necessary any more */
height: 150px;
background: #eee;
margin: 40px;
}
#popup {
position: fixed;
height: 30px;
background: gold;
display: none;
}
<div id="area">
Click here to shop popup, and scroll the window
</div>
<div id="popup">Popup fixed</div>
Pros:
- If placed outside of the parent (
#area
) - no additional code is necessary to prevent it from moving if the click initiated inside of it. - Better code reusability. Depending on the clicked element you can reuse the same popup by just changing its content.
- The wrapping parent element (
#area
) does not needposition
. Event.clientX
andEvent.clientY
is all it takes to move it to the new position.
Cons:
- If the page is scrolled, the popup position is fixed in relation to the window. A solution is to make it hide on page scroll, or more plicated - move it by the difference in coordinates.
3. (Best!) Move absolute (in-body) element to X,Y coordinates
Case: position: absolute;
popup as immediate child of body
X = Event.clientX + window.scrollX
Y = Event.clientY + window.scrollY
Example:
const el = (sel, par) => (par||document).querySelector(sel);
const elArea = el("#area");
const elPopup = el("#popup");
const showPopup = (evt) => {
Object.assign(elPopup.style, {
left: `${evt.clientX + window.scrollX}px`,
top: `${evt.clientY + window.scrollY}px`,
display: `block`,
});
};
elArea.addEventListener("click", showPopup);
body {
height: 300vh; /* Just to force some scrollbars */
}
#area {
/* position: relative; /* not necessary any more */
height: 150px;
background: #eee;
margin: 40px;
}
#popup {
position: absolute;
height: 30px;
background: gold;
display: none;
}
<div id="area">
Click here to shop popup, and scroll the window
</div>
<div id="popup">Popup fixed</div>
Pros:
- Even If the page is scrolled, the popup position is "anchored" in the same position relative to the document, not to the scrolling window.
- (Unless the
Event.currentTarget
is the entire"body"
) the popup will not change position if its contents are clicked.
Suggestions for all cases:
- For an improved UX (User Experience) a "floating" popup needs additional calculation, and that is — determining the remaining available space constraints to prevent the popup overflow the window right/bottom edges
- Additional code is necessary to close a Popup if the user clicks outside of it. This can be achieved by simply checking if on click — the
Event.target.closest("#popup") !== EL_popup
(Close the popup iftrue
). The same sometimes applies for Context-menus, but rarely for window-centered Modals — which have a dedicated close button.
Best practice example:
// DOM utility functions:
const el = (sel, par) => (par||document).querySelector(sel);
// Popup:
let elPopup; // To remember the currently active popup
const handlePopup = (evt) => {
// Get clicked target
const elTarget = evt.target;
// Clicked a popup, do nothing (Comment this line if not needed)
if (elTarget.closest(".popup")) return;
// Close currently open popup (if any):
if (elPopup) elPopup.classList.remove("is-active");
// Get initiator button
const elBtn = elTarget.closest("[data-popup]");
// Not a valid button
if (!elBtn) return;
// Get the popup
elPopup = el(elBtn.dataset.popup);
// No matching popup in this page, do nothing
if (!elPopup) return;
// Get its parent (BODY) so that we can calculate the min max
// available space
const elParent = elPopup.parentElement;
// Position:
const absX = evt.clientX + window.scrollX;
const absY = evt.clientY + window.scrollY;
const bcrParent = elParent.getBoundingClientRect();
const bcrPopup = elPopup.getBoundingClientRect();
const maxX = bcrParent.width - bcrPopup.width;
const maxY = bcrParent.height - bcrPopup.height;
const x = Math.max(0, Math.min(absX, maxX));
const y = Math.max(0, Math.min(absY, maxY));
// Show popup
Object.assign(elPopup.style, {
left: `${x}px`,
top: `${y}px`,
});
elPopup.classList.add("is-active");
};
el("body").addEventListener("click", handlePopup);
/*QuickReset*/ * { margin: 0; box-sizing: border-box; }
body {
min-height: 300vh; /* just to force some demo scrollbars */
}
#area {
background: #eee;
padding: 10px;
}
.popup {
position: absolute;
background: gold;
visibility: hidden;
pointer-events: none;
min-width: 100px;
padding: 1rem;
}
.popup.is-active {
visibility: visible;
pointer-events: auto;
}
<div id="area" data-popup="#popup-one">Show "popup one"</div>
<button data-popup="#popup-two" type="button">Show "popup two"</button>
<br>Click anywhere to close an open popup
<br>Click inside a popup. It will not close ()
<div class="popup" id="popup-one">Popup one!</div>
<div class="popup" id="popup-two">Popup TWO!</div>
本文标签: javascriptShow popup on mouse locationStack Overflow
版权声明:本文标题:javascript - Show popup on mouse location - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741216937a2360226.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论