javascript 에서 mouseover 와 mouseout 이벤트 최적화

4581 단어 JavaScript
이전에 개발 을 할 때 이 문제 에 부 딪 혔 는데 다음 과 같다.
어떤 용기 에 onmouseover 나 onmouseout 이벤트 가 연결 되 어 있 을 때 이 용기 에 다른 요소 노드 가 있 으 면 마우스 가 내부 에서 이동 할 때 onmouseover 와 onmouseout 이벤트 가 자주 발생 합 니 다.이것 은 실례 이 있 습 니 다. 다른 사람의 것 은 참고 하 셔 도 됩 니 다.
 
내 가 원 하 는 효 과 는 이벤트 가 마우스 로 요소 영역 에 들 어가 거나 벗 어 나 한 번 만 촉발 되 며, 마우스 가 요소 영역 내부 에서 이동 할 때 촉발 되 지 않 는 다 는 것 이다.
 
왜 이런 이유 가 생 겼 을 까?사실은 사건 의 거품 으로 인 한 것 이다.마우스 가 용기 의 하위 노드 를 위로 옮 기거 나 옮 길 때 각각 mouseover 와 mouseout 이 벤트 를 촉발 합 니 다. dom 트 리 를 따라 위로 거품 이 발생 하여 이벤트 처리 프로그램 (감청 기) 에 의 해 캡 처 되 거나 루트 노드 (document 또는 window) 에 거품 이 생 길 때 까지 전달 합 니 다. 즉, 이 벤트 는 부모 대상 에 게 보 냅 니 다.
 
문제 의 원인 을 알 게 되면 해결 하기 도 쉽 지 않 을까요?처음에 제 가 생각 했 던 것 은 이벤트 거품 을 없 애고 이벤트. cancelBubble = true (IE) 와 e. stopPropagation () (다른 브 라 우 저) 을 사용 하 는 것 이 었 습 니 다. 그런데 간단 한 테스트 를 해 보 니 효과 가 없 는 것 같 았 습 니 다. 문 제 는 여전 합 니 다. 거품 이 멈 추 지 않 는 것 같 습 니 다. 원인 이 불분명 합 니 다.(보충: 용기 에 있 는 a 링크 노드 의 거품 을 없 애 는 테스트 입 니 다. 하지만 마우스 가 위로 이동 하면 이벤트 가 발생 할 수 있 습 니 다. a 노드 아래 에 span 노드 가 있 습 니 다. 용기 에 있 는 모든 노드 를 거품 을 없 애 야 합 니까? 마음 있 는 사람 이 테스트 할 수 있 습 니 다. 정말 그렇다면 너무 징 그 럽 습 니 다. N 이 많은 노드 라면 거품 을 멈 춰 야 합 니까?)
 
사실 IE 아래 마우스 이벤트 에 mouseEnter 와 mouseLeave 가 있 습 니 다. 이것 은 용기 에 들 어 갈 때 한 번 촉발 되 고 내부 에서 이동 하면 촉발 되 지 않 습 니 다. 안 타 깝 게 도 IE 만 지원 합 니 다.우리 가 지금 해 야 할 일 은 '비 IE 브 라 우 저 에 mouseEnter 와 mouseLeave 지원 추가' 입 니 다.
 
jQuery 는 이렇게 하지 않 았 습 니 다. IE 와 다른 모든 브 라 우 저 에서 mouseover 와 mouseout 사건 을 직접 수정 하 였 습 니 다.jQuery 를 참고 하여 나 는 현재 나의 모든 코드 를 얻 었 다.
우선, 노드 대상 이 포함 되 어 있 는 지 판단 하 는 함수 contains 를 소개 합 니 다.
/* p=parentNode, c=childNode */
function contains(p,c){  
    return p.contains ? 
           p != c && p.contains(c) :
           !!(p.compareDocumentPosition(c) & 16);  
}

그 다음 에 중요 한 것 입 니 다. 여기 서 우 리 는 IE 에서 from Element 와 toElement 를 사 용 했 습 니 다. 이 두 가 지 는 IE 아래 의 마우스 가 올 라 갈 때 와 이동 할 때의 노드 대상 입 니 다.
/* e    ,target          */
function fixedMouse(e,target){  
        var related,
            type=e.type.toLowerCase();//        
        if(type=='mouseover'){
            related=e.relatedTarget||e.fromElement
        }else if(type='mouseout'){
            related=e.relatedTarget||e.toElement
        }else return true;
        return related && related.prefix!='xul' && !contains(target,related) && related!==target;
    }

그리고 우리 어떻게 쓰 지?예 를 들 어 귀속 이벤트 시,
//addListener          
addListener(target,'mouseover',function(e){
    e=e||window.event;
    if(fixedMouse(e, target)){
        //do something
    }
},false);

이렇게 하면 target 노드 를 옮 길 때 만 mouseover 와 mouseout 을 터치 합 니 다.
물론 위의 코드 를 mouseEnter 와 mouseLeave 로 따로 밀봉 할 수도 있 습 니 다. 나중에 호출 할 때 mouseover 와 mouseout 을 구별 할 수 있 습 니 다.
구체 적 인 demo 는 제 가 새로운 주제 가 출시 될 때 보 여 드릴 수 있 습 니 다.또는 여기 댓 글 부분. 의 답장, 인용 버튼 의 현 은 을 보면 위 에서 말 한 것 을 사용 합 니 다.
 
 

좋은 웹페이지 즐겨찾기