单击外部时隐藏Angular UI Bootstrap popover

bry*_*yan 46 javascript twitter-bootstrap angularjs angular-ui-bootstrap

我试图手动关闭一个引导程序弹出窗口,以便当我点击documentbody不是弹出窗口上的任何地方时关闭它.

我发现最接近完成此任务的是创建一个指令(找到这个答案),但这是一个手动触发器,如果​​变量是truefalse.

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

我不介意使用jQuery $(document).click(function(e){});我不知道如何调用close.

<div id="new_button" popover-template="plusButtonURL" popover-placement="right" popover-append-to-body="true" popover-animation="false">+</div>
Run Code Online (Sandbox Code Playgroud)

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

icf*_*ntv 42

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

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

  • 有一个例子,如何使用`popover-is-open`在任何地方点击外面时关闭popover? (4认同)

cda*_*uth 28

从Angular UI Bootstrap 1.0.0开始,outsideClick工具提示和弹出窗口就有了一个新的触发器(在这个拉取请求中引入.在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>
Run Code Online (Sandbox Code Playgroud)

此代码适用于旧版本的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>
Run Code Online (Sandbox Code Playgroud)

  • 从2015年开始不确定,但现在触发器是一个角度表达式,所以它必须是'popover-trigger ="'outsideClick'"`. (2认同)

jme*_*e11 23

编辑:

Plunker演示

这是它的工作原理(仍然冗长而详尽的解释):

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

创建一个自定义指令来定位触发器元素:

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

自定义指令

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

应用于按钮

<button popover-template="dynamicPopover.templateUrl" popover-title="{{dynamicPopover.title}}" class="btn btn-default" popover-elem>Popover With Template</button>
Run Code Online (Sandbox Code Playgroud)

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

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

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

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)
          }
        }
      });
    }
  };
});
Run Code Online (Sandbox Code Playgroud)

我将其添加到body标签中,以便整个页面*作为弹出窗口的可允许背景:

<body popover-close exclude-class="exclude">
Run Code Online (Sandbox Code Playgroud)

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

<input type="text" ng-model="dynamicPopover.title" class="form-control exclude">
Run Code Online (Sandbox Code Playgroud)

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

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

在Chrome,Firefox和Safari中测试过.

  • 我不得不将我的代码更改为[this](http://pastebin.com/nR7XXfMa)因为我假设的弹出窗口的动态加载.但这最终起作用了.谢谢你@ jme11 (2认同)

Pat*_*ard 13

有一个名为的属性popover-trigger,您可以将属性分配focus给.

<button 
      popover-placement="right" 
      popover="On the Right!" 
      popover-trigger="focus" 
      class="btn btn-default">
   Right
</button>
Run Code Online (Sandbox Code Playgroud)

这就是诀窍!:)

编辑:要允许单击工具提示而不是触发焦点丢失,请考虑类似于此的方法

如果您希望它以角度工作,请尝试创建自己的触发器定义.关于如何做到这一点的建议可以在这里找到.


aji*_*jin 13

popover-trigger="'outsideClick'" 这将完美地工作.

popover-trigger="outsideClick" 这不会.

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

这是因为他们使用这段代码检查了这个, "if (trigger === 'outsideClick')"


小智 6

你在寻找什么

<button
      popover-trigger="outsideClick" 
      class="btn btn-default">
   Right
</button>
Run Code Online (Sandbox Code Playgroud)

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


小智 5

您可以使用:

标记

<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>
Run Code Online (Sandbox Code Playgroud)

Javascript

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