计算相对内部的居中绝对div

时间:2013-10-29 22:15:02

标签: javascript jquery html css css3

我正在使用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;
}

并使用此信息并将按钮置于

// center the element based on visible screen-frame
function elementPosition (element) {
    var visibleRect = elementVisibleRect(element);
    $('.editHoverButton').css({
        top: visibleRect.top + ((visibleRect.height / 2) - ($('.editHoverButton').outerHeight() / 2)),
        left: visibleRect.left + (visibleRect.width / 2) - ($('.editHoverButton').outerWidth() / 2)
    });
}

现在我的问题是第三方库要求父DIV将浏览器默认的“静态”更改为“相对”,这会破坏我在第二个函数中的计算。

可能会迟到,但无论我尝试什么,我都无法弄清楚当父元素的位置设置为相对时如何使其工作。我似乎无法将数学弄得恰到好处,而且我的头脑开始受伤了。有什么建议吗?

编辑 - 添加了JSFIDDLE

http://jsfiddle.net/RhTY6/

2 个答案:

答案 0 :(得分:3)

具有absolute定位的元素将从自然流中移除(例如,它们不会留下它们所在的空间)并相对于其第一个父级定位而非static定位< / strong>即可。由于右侧框的位置为relative(不是static),因此您可以使用top: 50%;left: 50%;定位按钮。这将使左上角位于父级的中心。然后,您需要做的就是使用margin-topmargin-left从位置中减去元素高度和宽度的一半。这比你正在做的要简单得多,如下所示:

JavaScript的:

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

CSS:

.editHoverButton {
  position: absolute;
  z-index: 99;
  font-family: sans-serif;
  font-size: 14px;
  font-weight: normal;
  background-color: #00bb00;
  top: 50%;
  left: 50%;
}

除了从this功能中删除elementPosition()之外,别无其他任何更改。

DEMO(请注意左边的一个不再有效。这是因为它位于static。)

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

问题在于,在定义rect时,您已经占据了元素的顶部和左侧位置。关于定位计算。将这些更改为0(不是最好的方法,但它有效)可以解决relative元素的问题。

DEMO(请注意,左边的确实有效。这是因为无论如何它都位于0,0。

编辑 - 当页面滚动时,这将有效:

这将容器设置在一个变量中,这样当页面滚动时,它可以自动重新定位。

DEMO

答案 1 :(得分:1)

编辑:通过改变脚本使其与CSS和HTML(相对和绝对定位)一起使用。

水平轴计算完全缺失(我已应用了应用于垂直轴的相同计算)。

我已经添加了一些数据和一个标尺来帮助你完成这项工作:正如你所看到的,它是(并且它是你原来的小提琴)不是完全居中(显然你需要)

当容器小于视口时查看它,但这很容易解决。

Running Demo

尝试调整小提琴窗口的大小并垂直和水平滚动以查看它是否有效。

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