2017-12-25 18 views
1

하자. 그가 <a> 태그를 클릭 할 때마다 사용자에게 경고하고 싶다고합시다.각. 한 번만 이벤트를 바인딩하십시오 (첫 번째 초기화시)

document.querySelector('body').addEventListener('click', function (event : any) { 
      if (event.target.tagName === 'A') { 
       event.preventDefault(); 
       alert('Congratulations! A tag clicked!!!'); 
      } 
     }); 

나는 이것이 내가이 구성 요소 (라우터 링크)에 갈 때마다 새로운 바인딩 (그리고 한 번 더 경고를)해야합니다 (ngOnInit()에에) constructor 바인딩 넣어합니다.
첫 번째 초기화에서 한 번만 바인딩하는 방법은 무엇입니까?

그 사이에 나는 을 ngOnDestroy()에 사용합니다. 추악한 것 같습니다. 더 좋은 점이 있습니까?

답변

1

원하는 이벤트 리스너가 이미 요소에 있는지 여부를 확인해야하는 것처럼 보입니다. 를 참조하십시오 :이 같은 것을 사용하는 권합니다 this answer을 바탕으로 How to check whether dynamically attached event listener exists or not?

(적어도 나를 위해 작동) :

function showAlert(evt) { 
    evt.preventDefault(); 
    alert('Congratulations! A tag clicked!!'); 
} 

    const aTags = document.querySelectorAll('a'); 
    for (const i in aTags) { 
    const element = aTags[i]; 
     if (element instanceof Element && element.getAttribute('listener') !== 'true') { 
     element.addEventListener('click', showAlert); 
     element.setAttribute('listener', 'true'); 
    } 
    } 

당신처럼 몸 전체에 이벤트 리스너를 결합해야하는 경우 예를 들어 정적 변수를 사용할 수 있습니다. 구성 요소 시작 부분에 하나 만들고 이벤트 리스너를 바인딩하기 전에 값을 확인하십시오. 예 :

export class CongratulationsComponent implements OnInit { 
    static flag = true; 
    constructor() {} 

    ngOnInit() { 
    if (CongratulationsComponent.flag) { 
     document.querySelector('body').addEventListener('click', function (event: any) { 
     if (event.target.tagName === 'A') { 
      event.preventDefault(); 
      alert('Congratulations! A tag clicked!!!'); 
     } 
     }); 
     CongratulationsComponent.flag = false; 
    } 
    } 
}