关闭所有Angular JS Bootstrap popovers,点击屏幕上的任意位置?

时间:2014-04-07 15:15:37

标签: javascript jquery angularjs twitter-bootstrap

我正在使用Angular指令进行引导。

我的示例中有一个弹出窗口:

<button popover="Hello, World!" popover-title="Title" class="btn btn-default ng-scope">Dynamic Popover</button>

再次单击按钮时会关闭。当用户点击任何地方时,我想关闭它 - 以及任何其他开放式弹出窗口。

我没有看到内置的方法来做到这一点。

8 个答案:

答案 0 :(得分:9)

angular.element(document.body).bind('click', function (e) {
    var popups = document.querySelectorAll('.popover');
    if(popups) {
        for(var i=0; i<popups.length; i++) {
            var popup = popups[i];
            var popupElement = angular.element(popup);

            if(popupElement[0].previousSibling!=e.target){
                popupElement.scope().$parent.isOpen=false;
                popupElement.remove();
            }
        }
    }
});

答案 1 :(得分:2)

正在跟踪此功能请求(https://github.com/angular-ui/bootstrap/issues/618)。与aet的答案类似,您可以执行功能请求中建议的操作:

$('body').on('click', function (e) {
   $('*[popover]').each(function () {
        //Only do this for all popovers other than the current one that cause this event
        if (!($(this).is(e.target) || $(this).has(e.target).length > 0) 
             && $(this).siblings('.popover').length !== 0 
             && $(this).siblings('.popover').has(e.target).length === 0)                  
        {
             //Remove the popover element from the DOM          
             $(this).siblings('.popover').remove();
             //Set the state of the popover in the scope to reflect this          
             angular.element(this).scope().tt_isOpen = false;
        }
    });
});

(来源:vchatterji在上述功能请求中的评论)

功能请求还有一个非jQuery解决方案以及此plnkr:http://plnkr.co/edit/fhsy4V

答案 2 :(得分:2)

        angular.element(document.body).bind('click', function (e) {
            var popups = document.querySelectorAll('.popover');
            if (popups) {
                for (var i = 0; i < popups.length; i++) {
                    var popup = popups[i];
                    var popupElement = angular.element(popup);
                    console.log(2);
                    if (popupElement[0].previousSibling != e.target) {
                        popupElement.scope().$parent.isOpen = false;
                        popupElement.scope().$parent.$apply();
                    }
                }
            }
        });

答案 3 :(得分:0)

一个想法是你可以改变触发器来使用鼠标进入和退出,这将确保一次只显示一个弹出窗口。以下是一个例子:

<button popover="I appeared on mouse enter!"
        popover-trigger="mouseenter" class="btn btn-default"
        popover-placement="bottom" >Hello World</button>

您可以看到此工作in this plunker。您可以在angular bootstrap site上找到工具提示触发器的完整列表(工具提示和弹出窗口具有相同的触发器选项)。祝你好运!

答案 4 :(得分:0)

你说的是弹出窗口的默认设置,但你可以使用触发器功能控制它,方法是将模糊放在触发器的第二个参数中,如popover-trigger="{mouseenter:blur}"

答案 5 :(得分:0)

有相同的要求,这就是我们这样做的方式: 首先,我们在工具提示的链接功能中修改了bootstrap:

if (prefix === "popover") {
    element.addClass('popover-link');
}

然后,我们在主体上运行一个点击处理程序,如下所示:

$('body').on('click', function(e) {
    var clickedOutside = true;
    // popover-link comes from our modified ui-bootstrap-tpls
    $('.popover-link').each(function() {
        if ($(this).is(e.target) || $(this).has(e.target).length) {
            clickedOutside = false;
            return false;
        }
    });
    if ($('.popover').has(e.target).length) {
        clickedOutside = false;
    }
    if (clickedOutside) {
        $('.popover').prev().click();
    }

});

答案 6 :(得分:0)

我在下面的代码中使用相同的

    angular.element(document.body).popover({
        selector: '[rel=popover]',
        trigger: "click"
    }).on("show.bs.popover", function(e){
        angular.element("[rel=popover]").not(e.target).popover("destroy");
         angular.element(".popover").remove();
    });

答案 7 :(得分:-2)

谢谢Lauren Campregher,这是有效的。

您的代码是唯一也在范围内运行状态更改的代码。

仅配置为如果您单击弹出框,后者将关闭。

我已经混合了你的代码,现在如果你在popover中点击它也可以。

系统是否通过popover-template完成,

为了使用popover-template完成可识别弹出窗口,我使用了类popover-body和popover-title,对应于使用模板制作的标题和弹出框的主体,并确保它直接指向它们放在代码中:

angular.element(document.body).bind('click', function (e) {
    var popups = document.querySelectorAll('.popover');
    if(popups) {
        for(var i=0; i<popups.length; i++) {
            var popup = popups[i];
            var popupElement = angular.element(popup);        

            var content;
            var arrow;
            if(popupElement.next()) {
              //The following is the content child in the popovers first sibling
              // For the classic popover with Angularjs Ui Bootstrap
              content = popupElement[0].querySelector('.popover-content');


              // For the templating popover (popover-template attrib) with Angularjs Ui Bootstrap              
              bodytempl = popupElement[0].querySelector('.popover-body');
              headertempl= popupElement[0].querySelector('.popover-title');


              //The following is the arrow child in the popovers first sibling
              // For both cases.
              arrow = popupElement[0].querySelector('.arrow');              
            }



            if(popupElement[0].previousSibling!=e.target && e.target != content && e.target != arrow && e.target != bodytempl && e.target != headertempl){
                popupElement.scope().$parent.isOpen=false;
                popupElement.remove();
            }

        }
    }
});

祝你有个美好的一天,谢谢Lauren,谢谢你AngularJS,非常感谢你堆叠家庭!

<强>更新

我更新了所有添加额外控件。 弹出窗口中的元素被排除在控件之外(例如,插入到弹出框体中的图片)。然后点击相同的关闭。

我曾经解决过API Node.contains的命令,它集成在一个返回true或false的函数中。

现在放置任何元素,运行控件,如果单击内部,则保持弹出窗口打开:

// function for checkparent with Node.contains
function check(parentNode, childNode) { if('contains' in parentNode) {      return parentNode.contains(childNode);  }   else {      return parentNode.compareDocumentPosition(childNode) % 16;  }}

angular.element(document.body).bind('click', function (e) {
    var popups = document.querySelectorAll('.popover');
    if(popups) {
        for(var i=0; i<popups.length; i++) {
            var popup = popups[i];
            var popupElement = angular.element(popup);        

            var content;
            var arrow;
            if(popupElement.next()) {
              //The following is the content child in the popovers first sibling
              // For the classic popover with Angularjs Ui Bootstrap
              content = popupElement[0].querySelector('.popover-content');


              // For the templating popover (popover-template attrib) with Angularjs Ui Bootstrap              
              bodytempl = popupElement[0].querySelector('.popover-body');
              headertempl= popupElement[0].querySelector('.popover-title');


              //The following is the arrow child in the popovers first sibling
              // For both cases.
              arrow = popupElement[0].querySelector('.arrow');              
            }

        var checkel= check(content,e.target);

            if(popupElement[0].previousSibling!=e.target && e.target != content && e.target != arrow && e.target != bodytempl && e.target != headertempl&& checkel == false){
                popupElement.scope().$parent.isOpen=false;
                popupElement.remove();
            }

        }
    }
});