187

これが例です。多くのサイトのように画像オーバーレイを作成したいとします。したがって、サムネイルをクリックすると、ウィンドウ全体に黒いオーバーレイが表示され、画像の拡大版がウィンドウの中央に配置されます。黒いオーバーレイをクリックすると、それが閉じられます。画像をクリックすると、次の画像を表示する関数が呼び出されます。

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の方法があるかどうかを知りたいです。

4

10 に答える 10

198

@JosephSilberが言ったこと、または$ eventオブジェクトをng-clickコールバックに渡して、その中の伝播を停止します。

<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
}
于 2013-03-04T02:30:49.547 に答える
174

使用$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

于 2013-03-04T02:19:23.780 に答える
101

私はこれにディレクティブを使用するというアイデアが好きです:

.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>

必要に応じて、別の質問に対するこの回答のように、このソリューションをより一般的にすることができます:https ://stackoverflow.com/a/14547223/347216

于 2013-11-07T20:52:58.893 に答える
32

場合によっては、これを行うだけで最も理にかなっていることがあります。

<widget ng-click="myClickHandler(); $event.stopPropagation()"/>

myClickHandler()使用された他の多くの場所でイベントの伝播を停止したくなかったので、この方法を選択しました。

確かに、ハンドラー関数にブールパラメーターを追加することもできますが、stopPropagation()単なる。よりもはるかに意味がありtrueます。

于 2014-08-14T05:40:14.040 に答える
9

これは私のために働きます:

<a href="" ng-click="doSomething($event)">Action</a>

this.doSomething = function($event) {
  $event.stopPropagation();
  $event.preventDefault();
};
于 2016-09-01T08:48:54.840 に答える
4

すべてのリンクに停止伝播を追加する必要がない場合は、これも機能します。もう少しスケーラブル。

$scope.hideOverlay( $event ){

   // only hide the overlay if we click on the actual div
   if( $event.target.className.indexOf('overlay') ) 
      // hide overlay logic

}
于 2013-09-19T11:15:18.457 に答える
0

テンプレートの親要素にng-click="$ event.stopPropagation"を挿入すると、stopPropogationがツリーをバブルアップするときにキャッチされるため、テンプレート全体に対して1回だけ書き込む必要があります。

于 2016-04-21T02:56:15.497 に答える
0

別のディレクティブを登録して、その上にイベント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();
                });
            };
        }
    }
});
于 2016-07-22T09:41:38.213 に答える
0
<div ng-click="methodName(event)"></div>

INコントローラーの使用

$scope.methodName = function(event) { 
    event.stopPropagation();
}
于 2017-06-07T02:41:58.143 に答える
0

私の場合event.stopPropagation();、リンクを押すたびにページを更新していたので、別の解決策を見つける必要がありました。

だから私がしたことは、親のイベントをキャッチし、それが実際にを使用して彼の子供から来ている場合はトリガーをブロックすることでしたevent.target

解決策は次のとおりです。

if (!angular.element($event.target).hasClass('some-unique-class-from-your-child')) ...

したがって、基本的に、親コンポーネントからのng-clickは、親をクリックした場合にのみ機能します。子をクリックすると、この条件に合格せず、フローが続行されません。

于 2020-10-27T13:32:27.463 に答える