我正在处理一个弹出框,当光标悬停在元素上时,弹出框显示一些文本与元素之间的某个位置。您可以在这里看到一个简化的演示:https://jsfiddle.net/xsvm2Lur/61/
现在,弹出框将压扁当它靠近包围框。我希望弹出窗口出现在悬停元素的左下角(如果弹出窗口将向右溢出)或左上角(如果弹出窗口将溢出到下端和右侧),如果弹出窗口将溢出。
将显示的位置和文本是动态生成的(例如,在呈现之前我不知道)。
现在,我有一个使用Javascript的工作版本。我的做法是:
textLength
吧。这将被设置为弹出的宽度,所以所有的文本进入1行。textLength
+x位置>框宽,则在x轴上“反转”弹出框,方法是通过textLength
推导弹出框的“左”值,并与元素相距一段距离。这个解决方案是可行的,但我想知道是否有更好的方法可以做到这一点而不需要计算字符,或者是否有其他方法来优雅地完成它,也许CSS只有在没有Javascript的情况下呢?
发布于 2022-04-20 01:31:56
遗憾的是,我不相信只有CSS才能做到这一点。但是,通过处理您的小提琴,我成功地添加了您想要的功能。
我这样做只是为了包含对容器的引用,并检查弹出位置和大小是否在容器BoundingClientRect中。
这是popupShow函数的更新代码:
const showPopup = (top, left, text, container) => {
popup.textContent = text;
const containerBCR = container.getBoundingClientRect();
const popupBCR = popup.getBoundingClientRect();
const popupWidth = popupBCR.width,
popupHeight = popupBCR.height;
let popupTop = top + 20,
popupLeft = left + 20,
newPopupWidth;
console.log("height: ", popupHeight);
console.log("top: ", top);
console.log("bottomPopup: ", top + 20 + popupHeight);
console.log("bottomBoundary", containerBCR.bottom);
if (left + 20 + popupWidth > containerBCR.right) {
popupLeft = left - popupWidth;
if (popupLeft < containerBCR.left) {
popupLeft = containerBCR.left;
newPopupWidth = left - containerBCR.left;
}
}
if (top + 20 + popupHeight > containerBCR.bottom) {
popupTop = top - popupHeight;
if (popupTop < containerBCR.top) {
popupTop = containerBCR.top;
}
}
popup.style.top = popupTop + "px";
popup.style.left = popupLeft + "px";
popup.style.width = newPopupWidth;
popup.style.visibility = 'visible';
}
如您所见,我还编辑了弹出窗口,使用“可见性:隐藏”而不是“显示:无”。这是因为如果显示设置为"none",我们将无法得到他的大小(不过,可能会有解决办法)。
试着检查一下更新小提琴,告诉我你的想法。
我把一个圆圈往下推了一点,因为代码目前没有检查弹出窗口的填充,所以它溢出了一点(几个像素)。
发布于 2022-04-20 01:31:44
这是基于象限,简单计算,如果我们是超过50%的宽度和/或高度,并互换风格使用右或底部代替。这不关心弹出的内容,不需要测量。
const popup = document.getElementById("pop-up")
const parsePx = (px) => parseFloat(px.slice(0, -2))
const showPopup = (text, position) => {
popup.textContent = text;
popup.style.top = position.top;
popup.style.left = position.left;
popup.style.right = position.right;
popup.style.bottom = position.bottom;
popup.style.display = 'inline-block';
}
const hidePopup = () => {
popup.style.display = 'none';
}
const circles = document.querySelectorAll(".red-circle")
circles.forEach(el => el.addEventListener('mouseover', (e) => {
const hoveredEl = e.target;
const textContent = hoveredEl.getAttribute('data-content');
//get absolute position of elements
let elBounds = hoveredEl.getBoundingClientRect();
//get absolute position of parent;
let ctBounds = popup.parentElement.getBoundingClientRect();
//calculate relative positions
let left = elBounds.left - ctBounds.left + (elBounds.width / 2),
top = elBounds.top - ctBounds.top + (elBounds.height / 2),
width = ctBounds.width,
height = ctBounds.height
//prepare position settings
let position = { left: "auto", top: "auto", bottom: "auto", right: "auto" }
//calculate if we're over 50% of box size
if(top>ctBounds.height/2) position.bottom = ctBounds.height - top + 20 + 'px'; else position.top = top + 20 + 'px';
if(left>ctBounds.width/2) position.right = ctBounds.width - left + 20 + 'px'; else position.left = left + 20 + 'px';
showPopup(textContent, position);
}))
circles.forEach(el => el.addEventListener('mouseout', (e) => { hidePopup() }))
.container { width: 200px; height: 200px; border: 1px solid black; position: relative;}
.red-circle { border-radius: 50%; background: red; width: 20px; height: 20px; position: absolute;}
#pop-up { background-color: #EFEFEF; padding: 0.25em; position: absolute;}
<div class="container">
<div style="top:20px;left:20px;" class="red-circle" data-content="This is a red circle"></div>
<div style="top:10px;left:150px;" class="red-circle" data-content="This is the top-right red circle"></div>
<div style="top:140px;left:150px;" class="red-circle" data-content="This is the bottom-right red circle"></div>
<div style="top:140px;left:15px;" class="red-circle" data-content="This is the bottom-left red circle"></div>
<span style="display:hidden" id="pop-up"></span>
</div>
https://stackoverflow.com/questions/71936872
复制相似问题