取消嵌套的ng点击调用之间的事件传播的最好方法是什么?
这是一个例子。 比方说,我想有一个像许多网站的图像覆盖。 所以,当你点击一个缩略图时,整个窗口上会出现一个黑色的叠加层,而图像的一个更大的版本则以它为中心。 点击黑色覆盖层就会解散它。 点击图像将调用一个显示下一个图像的函数。
html:
<div ng-controller="OverlayCtrl" class="overlay" ng-click="hideOverlay()"> <img src="http://some_src" ng-click="nextImage()"/> </div>
javascript:
function OverlayCtrl($scope) { $scope.hideOverlay = function() { // Some code to hdie the overlay } $scope.nextImage = function() { // Some code to find and display the next image } }
问题是,在这个设置下,如果你点击图片, nextImage()
和hideOverlay()
被调用。 但是我想要的只是nextImage()
被调用。
我知道你可以在nextImage()
函数中捕获和取消事件,如下所示:
if (window.event) { window.event.stopPropagation(); }
…但是我想知道是否有一个更好的AngularJS方法,不需要我用这个代码片段在叠加层中的元素前加上所有的函数。
@JosephSilber说了什么,或者将$ event对象传递给ng-click
callback,并停止它内部的传播:
<div ng-controller="OverlayCtrl" class="overlay" ng-click="hideOverlay()"> <img src="http://some_src" ng-click="nextImage($event)"/> </div>
$scope.nextImage = function($event) { $event.stopPropagation(); // Some code to find and display the next image }
使用$event.stopPropagation()
:
<div ng-controller="OverlayCtrl" class="overlay" ng-click="hideOverlay()"> <img src="http://some_src" ng-click="nextImage(); $event.stopPropagation()" /> </div>
这是一个演示: http : //plnkr.co/edit/3Pp3NFbGxy30srl8OBmQ?p=preview
我喜欢使用这个指令的想法:
.directive('stopEvent', function () { return { restrict: 'A', link: function (scope, element, attr) { element.bind('click', function (e) { e.stopPropagation(); }); } }; });
然后使用下面的指令:
<div ng-controller="OverlayCtrl" class="overlay" ng-click="hideOverlay()"> <img src="http://some_src" ng-click="nextImage()" stop-event/> </div>
如果你想,你可以使这个解决scheme更通用,就像这个答案不同的问题: https : //stackoverflow.com/a/14547223/347216
有时候,这样做可能是最有意义的:
<widget ng-click="myClickHandler(); $event.stopPropagation()"/>
我select这样做,因为我不希望myClickHandler()
在许多其他地方停止事件传播。
当然,我可以添加一个布尔参数给处理函数,但是stopPropagation()
比true
更有意义。
这适用于我:
<a href="" ng-click="doSomething($event)">Action</a> this.doSomething = function($event) { $event.stopPropagation(); $event.preventDefault(); };
如果你不想把停止传播添加到所有的链接,这也适用。 有点可扩展性。
$scope.hideOverlay( $event ){ // only hide the overlay if we click on the actual div if( $event.target.className.indexOf('overlay') ) // hide overlay logic }
如果在模板的父元素中插入ng-click =“$ event.stopPropagation”,则stopPropogation将被捕获,因为它会冒泡树,所以您只需为整个模板编写一次。
您可以在ng-click
之上注册另一个指令,修改ng-click
的默认行为并停止事件传播。 这样你就不必手工添加$event.stopPropagation
。
app.directive('ngClick', function() { return { restrict: 'A', compile: function($element, attr) { return function(scope, element, attr) { element.on('click', function(event) { event.stopPropagation(); }); }; } } });
IN控制器使用
$ scope.methodName = function(event){event.stopPropagation();}