3

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

4

2 回答 2

3

具有absolute定位的元素从自然流中移除(例如,它们不会在原来的位置留下空间)并相对于它们的第一个父元素进行定位,而不是static定位。由于右侧框的定位是relative(not ),您可以使用和static定位按钮。这将使左上角位于父级的中心。然后你所要做的就是从位置中减去元素的一半高度和宽度,使用and 。这比您所做的要简单得多,如下所示: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

于 2013-11-01T00:57:17.950 回答
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;
}
于 2013-11-01T00:13:21.603 回答