source

네스트된ng클릭콜간의이벤트 전파를 취소하는 가장 좋은 방법은 무엇입니까?

gigabyte 2023. 3. 10. 22:03
반응형

네스트된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();
}

하지만 더 나은 앵글이 있는지 알고 싶어요이 스니펫을 사용하여 오버레이 내부의 모든 요소에 있는 모든 기능을 접두사로 붙일 필요가 없는 JS 방식입니다.

@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
}

사용하다$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>

필요에 따라서, 이 솔루션을 보다 범용적으로 할 수 있습니다.이러한 질문에 대한 답변은, https://stackoverflow.com/a/14547223/347216 에서 확인할 수 있습니다.

다음과 같이 하는 것이 가장 타당할 수 있습니다.

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

이런 식으로 하기로 한 건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"을 삽입하면 stopPropagation이 트리에 거품이 생길 때 포착되므로 템플릿 전체에 대해 한 번만 작성하면 됩니다.

위에 다른 지시문을 등록할 수 있습니다.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();
                });
            };
        }
    }
});
<div ng-click="methodName(event)"></div>

IN 컨트롤러 사용

$scope.methodName = function(event) { 
    event.stopPropagation();
}

저 같은 경우에는event.stopPropagation();링크를 누를 때마다 페이지가 새로 고쳐져서 다른 해결책을 찾아야 했습니다.

가 한 로부터 온 이다.event.target.

해결책은 다음과 같습니다.

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

따라서 기본적으로 부모 컴포넌트에서 ng클릭은 부모 컴포넌트를 클릭한 경우에만 작동합니다.아이를 클릭하면 이 조건을 통과하지 못하고 흐름이 계속되지 않습니다.

언급URL : https://stackoverflow.com/questions/15193539/whats-the-best-way-to-cancel-event-propagation-between-nested-ng-click-calls

반응형