How can you ensure twitter bootstrap popover windows are visible?

后端 未结 2 1579
情话喂你
情话喂你 2020-12-23 22:52

Does anyone know of an extension to the popover component of twitter bootstrap that dynamically changes the placement option to ensure that the popover displays on the scree

2条回答
  •  一整个雨季
    2020-12-23 23:21

    For those interested in a solution that will take a default placement (using the data-placement attribute on the element), I have adapted the great answer from Cymen.

    I've also ensured that no boundaries are calculated unnecessarily, so it should be slightly more performant.

    $('[data-toggle="popover"]').each(function() {
        var trigger = $(this);
        trigger.popover({
            animation: true,
            delay: { show: 0, hide: 0 },
            html: true,
            trigger: 'hover focus',
            placement: getPlacementFunction(trigger.attr("data-placement"), 283, 117)
        });
    });
    
    var getPlacementFunction = function (defaultPosition, width, height) {
        return function (tip, element) {
            var position, top, bottom, left, right;
    
            var $element = $(element);
            var boundTop = $(document).scrollTop();
            var boundLeft = $(document).scrollLeft();
            var boundRight = boundLeft + $(window).width();
            var boundBottom = boundTop + $(window).height();
    
            var pos = $.extend({}, $element.offset(), {
                width: element.offsetWidth,
                height: element.offsetHeight
            });
    
            var isWithinBounds = function (elPos) {
                return boundTop < elPos.top && boundLeft < elPos.left && boundRight > (elPos.left + width) && boundBottom > (elPos.top + height);
            };
    
            var testTop = function () {
                if (top === false) return false;
                top = isWithinBounds({
                    top: pos.top - height,
                    left: pos.left + pos.width / 2 - width / 2
                });
                return top ? "top" : false;
            };
    
            var testBottom = function () {
                if (bottom === false) return false;
                bottom = isWithinBounds({
                    top: pos.top + pos.height,
                    left: pos.left + pos.width / 2 - width / 2
                });
                return bottom ? "bottom" : false;
            };
    
            var testLeft = function () {
                if (left === false) return false;
                left = isWithinBounds({
                    top: pos.top + pos.height / 2 - height / 2,
                    left: pos.left - width
                });
                return left ? "left" : false;
            };
    
            var testRight = function () {
                if (right === false) return false;
                right = isWithinBounds({
                    top: pos.top + pos.height / 2 - height / 2,
                    left: pos.left + pos.width
                });
                return right ? "right" : false;
            };
    
            switch (defaultPosition) {
                case "top":
                    if (position = testTop()) return position;
                case "bottom":
                    if (position = testBottom()) return position;
                case "left":
                    if (position = testLeft()) return position;
                case "right":
                    if (position = testRight()) return position;
                default:
                    if (position = testTop()) return position;
                    if (position = testBottom()) return position;
                    if (position = testLeft()) return position;
                    if (position = testRight()) return position;
                    return defaultPosition;
            }
        }
    };
    

提交回复
热议问题