【问题标题】:Click outside div - when div has buttons that fires events - angularjs单击 div 外部 - 当 div 具有触发事件的按钮时 - angularjs
【发布时间】:2015-09-21 12:41:49
【问题描述】:

我正在使用以下指令来检测何时在 div 外部进行了点击:

app.directive('clickOut', function ($window, $parse) {
return {
    restrict: 'A',
    link: function (scope, element, attrs) {
        var clickOutHandler = $parse(attrs.clickOut);

        angular.element($window).on('click', function (event) {
            if (element[0].contains(event.target)) return;
            clickOutHandler(scope, {$event: event});
            scope.$apply();
        });
    }
  };
});

在这个 div 中:

             <div class="panel-body" click-out="closeMyPopup()">                 
                <div class="row clearfix">
                    <div class="col-md-12">
                        <div class="form-inline pull-right">
                            <button type="button" class="form-control btn"  ng-click="onCancelAnnouncement()">Cancel</button>
                            <button type="submit" class="form-control btn" ng-click="onSaveAnnouncement()">Save</button>
                        </div>

                    </div>
                </div>

            </div>

效果很好,当你在 div 外部点击时,函数 closeMyPopup() 被触发,问题是 div 有触发其他功能的按钮。由于某种原因,当调用其他函数时(例如单击按钮时),外部单击事件被触发调用 closeMyPopup(),按钮位于 div 内部,因此不应调用外部单击事件。我可以使用另一个指令,它具有正确的行为并且在您触发另一个功能时不会触发外部点击?或者我该如何解决这个问题?

我也使用这个其他指令,同样的问题:

app.directive("outsideClick", ['$document', '$parse', function      ($document, $parse) {
    return {
           link: function ($scope, $element, $attributes) {
        var scopeExpression = $attributes.outsideClick,
            onDocumentClick = function (event) {
                var isChild = $element.find(event.target).length > 0;

                if (!isChild) {
                    $scope.$apply(scopeExpression);
                }
            };

        $document.on("click", onDocumentClick);

        $element.on('$destroy', function () {
            $document.off("click", onDocumentClick);
        });
    }
  }
}]);

【问题讨论】:

    标签: javascript jquery angularjs angularjs-directive


    【解决方案1】:

    确切地说:事件将呈现给嵌套 DOM 层次结构中的每个对象,除非并且直到 停止它们的传播。当然,这是设计使然:JavaScript 不会假定“我能找到的最深处正在监听此事件的人”是唯一可能对它感兴趣的人。 每个人说他正在听它,有能力听到它的人都会听到它,轮到他们每个人......除非他们中的一个人明确地取消进一步的传播,JS 将停止寻找其他人将其发送给。 (没有人必须“将事件发送到外部容器。”相反,他们只需要告诉 JS 不要继续发送它。)

    【讨论】:

      【解决方案2】:

      这是因为事件正在传播到Window 对象。

      - Window
          - document
              - dialog
                 - button
      

      在上述层次结构中,如果最后一个 button 元素发生点击事件,则该事件将传播到父元素,直到到达 Window,然后将关闭您的对话框。

      解决方案 1:

      通过将事件作为参数传递并调用event.stopPropagation()函数来停止每个控制器函数中的事件传播:

      <button type="button" class="form-control btn"  ng-click="onCancelAnnouncement($event)">Cancel</button>
      

      ...

      $scope.onCancelAnnouncement($event) {
          $event.stopPropagation();
      }
      

      解决方案 2:

      让事件传播并检查目标元素:

      angular.element($window).on('click', function (event) {
              var target = $(event.target);
              if(target.attr("id") === "anyid") { // or target.hasClass("someclass")
                                                  // or target.closest(".some-selector")
                  // just ignore
              } else {
                  // Do whatever you need 
              }
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-12-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多