Javascript 计算相对内的中心绝对div

Javascript 计算相对内的中心绝对div,javascript,jquery,html,css,Javascript,Jquery,Html,Css,我使用2个Javscript方法在页面的静态元素中放置一个悬停按钮。居中的按钮输入第一个元素内,并使用绝对位置。我用于获取父元素测量值的代码: // calculate if the element is in the visible window function elementVisibleRect(element) { element = $(element); var rect = { top: Math.round(element.offset().to

我使用2个Javscript方法在页面的静态元素中放置一个悬停按钮。居中的按钮输入第一个元素内,并使用绝对位置。我用于获取父元素测量值的代码:

// calculate if the element is in the visible window
function elementVisibleRect(element) {
    element = $(element);
    var rect = {
        top: Math.round(element.offset().top),
        left: Math.round(element.offset().left),
        width: Math.round(element.outerWidth()),
        height: Math.round(element.outerHeight())
    };
    var scrollTop = $(window).scrollTop();
    var windowHeight = $(window).height();
    var scrollBottom = scrollTop + windowHeight;
    var elementBottom = Math.round(rect.height + rect.top);

    if (scrollTop < rect.top && scrollBottom > elementBottom) {
        return rect;
    }
    if (scrollTop > rect.top) {
        rect.top = scrollTop;
    }
    if (scrollBottom < elementBottom) {
        rect.height = scrollBottom - rect.top;
    } else {
        rect.height = windowHeight - (scrollBottom - elementBottom);
    }
    return rect;
}
现在我的问题是,第三方库要求父DIV将浏览器默认的“static”位置更改为“relative”,这破坏了我在第二个函数中的计算

它可能很晚了,但无论我怎么尝试,我似乎都不知道当父元素的position设置为relative时如何使它工作。我的数学似乎不太对头,我的头开始痛了。有什么建议吗

编辑-添加JSFIDLE


编辑:仅通过更改脚本,使其与CSS和HTML(相对和绝对位置)一起工作

水平轴计算完全丢失(我已经应用了与垂直轴相同的计算)

我添加了一些数据和标尺来帮助您完成这项工作:如您所见,它(在您最初的小提琴中也是如此)没有完全居中(显然,当容器小于视口时,您需要查看它),但这将很容易解决

尝试调整小提琴窗口的大小,并在垂直和水平方向上滚动以查看它是否正常工作

function elementVisibleRect(element) {
    $("#data").html("");

    element = $(element);
    var rect = {
        top: Math.round(element.offset().top),
        left: Math.round(element.offset().left),
        width: Math.round(element.outerWidth()),
        height: Math.round(element.outerHeight())
    };
    var scrollTop = $(window).scrollTop();
    var windowHeight = $(window).height();
    var scrollBottom = scrollTop + windowHeight;
    var elementBottom = Math.round(rect.height + rect.top);

    var scrollLeft = $(window).scrollLeft();
    var windowWidth = $(window).width();
    var scrollRight = scrollLeft + windowWidth;
    var elementRight = Math.round(rect.width + rect.left);


    addData("rect.top", rect.top);
    addData("rect.left", rect.left);
    addData("rect.width", rect.width);
    addData("rect.height", rect.height);
    addData("scrollTop", scrollTop);
    addData("windowHeight", windowHeight);
    addData("scrollBottom", scrollBottom);
    addData("elementBottom", elementBottom);
    addData("scrollLeft", scrollLeft);
    addData("windowWidth", windowWidth);
    addData("scrollRight", scrollRight);
    addData("elementRight", elementRight);


    if (rect.top < scrollTop) {
        rect.top = scrollTop;
    }
    if (scrollBottom < rect.top < scrollTop) {
        rect.top = scrollTop;
    }
    if (scrollBottom < elementBottom) {
        rect.height = scrollBottom - rect.top;
    } else {
        rect.height = windowHeight - (scrollBottom - elementBottom);
    }

    if (rect.left < scrollLeft) {
        rect.left = scrollLeft;
    }
    if (scrollRight < rect.left < scrollLeft) {
        rect.left = scrollLeft;
    }
    if (scrollRight < elementRight) {
        rect.width = scrollRight - rect.left;
    } else {
        rect.width = windowWidth - (scrollRight - elementRight);
    }

    return rect;
}
功能元素VisibleRect(元素){
$(“#数据”).html(“”);
元素=$(元素);
var rect={
top:Math.round(element.offset().top),
左:Math.round(element.offset().left),
宽度:Math.round(element.outerWidth()),
高度:Math.round(element.outerHeight())
};
var scrollTop=$(窗口).scrollTop();
var windowHeight=$(window.height();
var scrollBottom=scrollTop+窗口高度;
var elementBottom=Math.round(rect.height+rect.top);
var scrollLeft=$(窗口).scrollLeft();
var windowWidth=$(window.width();
var scrollRight=scrollLeft+窗口宽度;
var elementRight=Math.round(rect.width+rect.left);
addData(“rect.top”,rect.top);
addData(“rect.left”,rect.left);
添加数据(“矩形宽度”,矩形宽度);
添加数据(“垂直高度”,垂直高度);
addData(“scrollTop”,scrollTop);
添加数据(“窗口高度”,窗口高度);
addData(“滚动底部”,滚动底部);
添加数据(“elementBottom”,elementBottom);
addData(“scrollLeft”,scrollLeft);
addData(“windowWidth”,windowWidth);
addData(“scrollRight”,scrollRight);
添加数据(“elementRight”,elementRight);
if(rect.top
具有
绝对定位的元素将从自然流中移除(例如,它们不会在原来的位置留下空间)并相对于其第一个父元素进行非
静态定位
定位
。由于右侧方框的定位是相对的(而不是静态的),因此您可以将按钮定位在顶部:50%和<代码>左侧:50%。这将使左上角位于父对象的中心。然后,您所要做的就是使用
margintop
marginleft
从该位置减去元素高度和宽度的一半。这比您之前所做的要简单得多,如下所示:

JavaScript:

function elementPosition() {
    $('.editHoverButton').css('margin-top', 0 - $('.editHoverButton').outerHeight() / 2);
    $('.editHoverButton').css('margin-left', 0 - $('.editHoverButton').outerWidth() / 2);
};
CSS:

除了从
elementPosition()
函数中删除
之外,无需更改其他内容

(请注意,左边的一个不再工作。这是因为它位于
静态

编辑——使用相同的基本思想,此方法应该有效:

问题是,在定义
rect
时,您必须占据元素的顶部和左侧位置。关于定位计算。将它们更改为
0
(这不是最好的方法,但它很有效)修复了
相对
元素的问题

(请注意,现在左侧的不起作用了。这是因为它仍然位于0,0。)

EDIT——当页面滚动时,这将起作用:

这将在变量中设置容器,以便在页面滚动时自动重新定位


您可以尝试使用!覆盖第三方CSS的重要声明。只需确保正确地固定DOM即可。也许我没有说得很清楚,但我需要它保持相对于其他功能的位置,并且不能更改它。你能在Fiddle上发布一个与HTML和CSS一起使用的示例吗?不错,不敢相信我错过了尝试。尽管仍然有很多问题,但并不是像这把小提琴一样始终保持在可视区域的中心:是的,你应该调整你的脚本。如果您的div大于viewalbe区域,那么fixed将起作用(完全没有脚本,只是css居中),因为它与视口一起工作。如果div小于可视区域,则脚本将正常工作,因为它可以正确计算位置。灰色区域是指一个轴上的div大于可视区域(如水平方向),而另一个轴上的div小于可视区域(如垂直方向)。这是一个棘手的部分。
fixed
的问题是,它与可滚动窗口相关,这意味着如果在按钮可见时滚动,它就不会用t滚动
function elementPosition() {
    $('.editHoverButton').css('margin-top', 0 - $('.editHoverButton').outerHeight() / 2);
    $('.editHoverButton').css('margin-left', 0 - $('.editHoverButton').outerWidth() / 2);
};
.editHoverButton {
  position: absolute;
  z-index: 99;
  font-family: sans-serif;
  font-size: 14px;
  font-weight: normal;
  background-color: #00bb00;
  top: 50%;
  left: 50%;
}