单击外部时隐藏Angular UI Bootstrap popover

时间:2015-05-28 16:57:59

标签: javascript angularjs twitter-bootstrap angular-ui-bootstrap

当我点击不是弹出框的documentbody上的任何地方时,我正尝试手动关闭引导程序弹出窗口以使其关闭。

我发现最接近完成此操作的是创建一个指令(found this answer),但如果变量是 true false

如果我点击任何不是popover的东西,有人可以帮我弄清楚如何关闭它吗?

我不介意使用jQuery $(document).click(function(e){});我根本不知道如何致电结束。

<div id="new_button" popover-template="plusButtonURL" popover-placement="right" popover-append-to-body="true" popover-animation="false">+</div>

通常popover-trigger="focus"可以解决问题,但我的popover包含需要点击的内容。如果我使用焦点触发器,我的弹出窗口中有ng-click被忽略,所以我正在寻找一种不那么传统的方法来解决这个问题。

12 个答案:

答案 0 :(得分:42)

更新:在1.0版本中,我们添加了一个名为outsideClick的新触发器,当用户在弹出窗口或工具提示外单击时,它会自动关闭弹出窗口或工具提示。

从0.14.0版本开始,我们添加了通过tooltip-is-openpopover-is-open属性以编程方式控制工具提示/弹出窗口何时打开或关闭的功能。

答案 1 :(得分:28)

自Angular UI Bootstrap 1.0.0以来,工具提示和弹出窗口有一个新的outsideClick触发器(在this pull request中引入。在Angular UI Bootstrap 2.0.0中,popover-trigger已被修改为使用角度表达式(Changelog),因此必须将值放在引号中。此代码适用于当前版本的angular-ui:

<div id="new_button" uib-popover-template="plusButtonURL" popover-trigger="'outsideClick'"
    popover-placement="right" popover-append-to-body="true" popover-animation="false">+</div>

此代码适用于旧版Angular UI Bootstrap(2.0.0之前):

<div id="new_button" uib-popover-template="plusButtonURL" popover-trigger="outsideClick"
    popover-placement="right" popover-append-to-body="true" popover-animation="false">+</div>

答案 2 :(得分:23)

<强>编辑:

Plunker Demo

以下是它的工作原理(仍然是详尽无遗的解释):

  1. 创建一个自定义指令,允许您定位触发器元素。
  2. 创建一个添加到正文的自定义指令,它将找到触发元素并在单击时触发自定义事件。
  3. 创建一个自定义指令以定位触发器元素:

    您需要从打开弹出窗口的元素触发自定义事件处理程序(在演示中这是按钮)。挑战在于popover被附加为这个元素的兄弟,我总是认为当你遍历DOM并期望它具有特定的结构时,事情有更大的可能性。有几种方法可以定位触发器元素,但我的方法是在单击时为元素添加一个唯一的类名(我选择“触发器”)。在这种情况下,一次只能打开一个弹出窗口,因此使用类名是安全的,但您可以根据自己的喜好进行修改。

    自定义指令

    app.directive('popoverElem', function(){
      return{
        link: function(scope, element, attrs) {
          element.on('click', function(){
            element.addClass('trigger');
          });
        }
      }
    });
    

    应用于按钮

    <button popover-template="dynamicPopover.templateUrl" popover-title="{{dynamicPopover.title}}" class="btn btn-default" popover-elem>Popover With Template</button>
    

    为文档正文(或任何其他元素)创建自定义指令以触发popover关闭:

    最后一部分是创建一个自定义指令,该指令将定位触发元素并触发自定义事件,以便在单击应用它的元素时关闭弹出窗口。当然,您必须从'trigger'元素中排除初始单击事件,以及要在弹出框内部与之交互的任何元素。因此,我添加了一个名为exclude-class的属性,因此您可以定义一个类,您可以将该类添加到应忽略其单击事件的元素中(不会导致弹出窗口关闭)。

    为了清理,在触发事件处理程序时,我们删除了添加到触发器元素的触发器类。

    app.directive('popoverClose', function($timeout){
      return{
        scope: {
          excludeClass: '@'
        },
        link: function(scope, element, attrs) {
          var trigger = document.getElementsByClassName('trigger');
    
          function closeTrigger(i) {
            $timeout(function(){ 
              angular.element(trigger[0]).triggerHandler('click').removeClass('trigger'); 
            });
          }
    
          element.on('click', function(event){
            var etarget = angular.element(event.target);
            var tlength = trigger.length;
            if(!etarget.hasClass('trigger') && !etarget.hasClass(scope.excludeClass)) {
              for(var i=0; i<tlength; i++) {
                closeTrigger(i)
              }
            }
          });
        }
      };
    });
    

    我将此添加到body标签中,以便整个页面*作为popover的可允许背景:

    <body popover-close exclude-class="exclude">
    

    并且,我将exclude类添加到popover的输入中:

    <input type="text" ng-model="dynamicPopover.title" class="form-control exclude">
    

    所以,有一些调整和陷阱,但我会留给你:

    1. 如果未定义一个,则应在popover-close指令的link函数中设置默认排除类。
    2. 你需要知道popover-close指令是元素绑定的,所以如果你删除我在html和body元素上设置的样式以给它们100%的高度,你可以在视口中有“死区”你的内容没有填写。
    3. 在Chrome,Firefox和Safari中测试过。

答案 3 :(得分:13)

您可以将属性popover-trigger分配给focus

<button 
      popover-placement="right" 
      popover="On the Right!" 
      popover-trigger="focus" 
      class="btn btn-default">
   Right
</button>

这就是诀窍! :)

编辑: 为了允许点击工具提示而不是触发焦点丢失,请考虑一种方法similar to this

如果您希望它以角度工作,请尝试创建自己的触发器定义。有关如何执行此操作的建议可以是found here

答案 4 :(得分:12)

popover-trigger="'outsideClick'"这将完美无缺。

popover-trigger="outsideClick"这不会。

我花了一天的时间来解决为什么它不适合我。

这是因为他们使用此代码"if (trigger === 'outsideClick')"

进行检查

答案 5 :(得分:6)

您正在寻找的是

<button
      popover-trigger="outsideClick" 
      class="btn btn-default">
   Right
</button>

从文档中 - outsideClick触发器将使弹出窗口在单击时切换,并在单击任何其他内容时隐藏。

答案 6 :(得分:4)

您可以使用:

<强>标记

<div ng-app="Module">
    <div ng-controller="formController">
        <button uib-popover-template="dynamicPopover.templateUrl" popover-trigger="focus" 
          popover-placement="left" type="button" class="btn btn-default">
             Popover With Template
        </button>

        <script type="text/ng-template" id="myPopoverTemplate.html">
            <div>
                <span>prasad!!</span>
            </div>
        </script>
    </div>
</div>

<强>的Javascript

<script type="text/javascript">
    var app = angular.module("Module", ['ui.bootstrap']);
    app.controller("formController", ['$scope', function($scope) {
        $scope.dynamicPopover = {
            templateUrl: 'myPopoverTemplate.html'
        };
    }]);
</script>

答案 7 :(得分:2)

我有同样的问题,popover-trigger="'outsideClick'"为我工作。有趣的是文档没有说明这个问题。

答案 8 :(得分:1)

Angular boostrap ui新版本1.x具有出侧点击功能的功能。将其升级到新版本。

<button uib-popover-template="updatePassword.templateUrl" popover-title="Update Password" popover-trigger="outsideClick" popover-placement="right" popover-append-to-body="true">Click here</button>

它为我工作。

如果弹出窗口中有任何提交按钮或单击事件,

焦点将无效。所以这是有用的方法。

答案 9 :(得分:1)

$ uibTooltipProvider setTriggers 方法中的“ outsideClick ”选项怎么样?文档说“outsideClick触发器将导致工具提示在点击时切换,并在点击任何其他内容时隐藏。” Documentation

答案 10 :(得分:0)

onclick="void(0)"行为添加到您的某些背景元素中,这些元素在点按时会删除弹出窗口。

查看https://github.com/angular-ui/bootstrap/issues/2123

答案 11 :(得分:0)

1)将ng-bootstrap用于Popover。

2)将ng-bootstrap版本更新为3.0.0或更高版本。 即npm install --save @ ng-bootstrap / ng-bootstrap @ 3.0.0

3)更新后,您可以使用Ngbpopover的[autoClose]功能。

<button type="button" class="btn btn-outline-secondary" popoverTitle="Pop title" [autoClose]="true" ngbPopover="Click anywhere or press Escape to close (try the toggling element too)">Click to toggle</button>

4)希望对您有所帮助!