>  기사  >  웹 프론트엔드  >  javascript_javascript 스킬의 mouseover, mouseout 사용법에 대한 자세한 설명

javascript_javascript 스킬의 mouseover, mouseout 사용법에 대한 자세한 설명

WBOY
WBOY원래의
2016-05-16 15:49:431944검색

이 글은 실제로 이벤트 요소의 하위 요소가 버블링되는 것을 방지하지 않습니다...

이벤트가 트리거되어야 하는지 여부를 결정하기 위해 하위 요소가 이벤트 요소에 버블링될 때 판단하는 것뿐입니다. 아...아니요, 이벤트 함수에서 관련 작업을 실행할지 여부가 되어야 합니다...

우선 여기를 클릭하세요: 문제 발생

참고: jquery의 mouseover/out 이벤트에도 이 문제가 있습니다.

해결책 1:

IE에는 mouseover 및 mouseout을 대체하는 mouseenter 및 mouseleave 이벤트가 있습니다.

인터넷에는 이 두 이벤트가 IE에서만 지원되고 다른 브라우저에서는 지원되지 않는다는 의견이 많습니다.

그러나 최신 버전의 Firefox와 Google은 mouseenter와 mouseleave를 지원합니다! ! ! ! !

또한 IE의 지원 범위는 [ie5이므로 IE를 뿌리면 안 됩니다...

다른 브라우저에서 테스트됨:

Firefox/3.6.28에서는 Mouseenter 및 mouseleave가 지원되지 않습니다. 어떤 버전의 Firefox가 이 두 이벤트를 지원할지는 알 수 없습니다...

Opera9.50 Alpha 및 Opera9.00 Beta에서는 지원되지 않습니다. 사실 이제 Opera를 테스트할 필요가 없습니다. 최신 버전의 Opera는 웹킷 커널을 기반으로 합니다...

Google 하위 버전에서는 테스트를 거치지 않았습니다...

물론 이러한 이전 버전의 브라우저는 기본적으로 무시될 수 있으므로 이것이 최선의 해결책이 되어야 합니다. mouseover 및 mouseout를 대체하려면 mouseenter 및 mouseleave 이벤트를 사용하십시오.

이 두 가지 이벤트의 예를 보려면 여기를 클릭하세요: mouseenter 및 mouseleave

참고: jquery에는 모든 브라우저와 호환되는 mouseenter 및 mouseleave 이벤트도 있습니다.

해결책 2:

위의 방법은 이전 버전의 Firefox 및 Google에서 지원되지 않습니다. 최대한의 호환성을 원한다면 아래를 계속 읽어보세요

이벤트 관련 요소를 얻기 위해 var reltg = e.관련Target ? e.관련Target : e.type == 'mouseout' ? e.toElement : e.fromElement를 사용합니다. 그런 다음 이 이벤트 관련 요소와 이벤트 요소 간의 관계(포함된 관계)를 이용하여 관련 이벤트 처리를 수행할지 여부를 결정합니다.

mouseout 이벤트의 경우 reltg는 마우스 포인터가 대상을 떠날 때 들어가는 노드입니다.

mouseover 이벤트의 경우 reltg는 마우스 포인터가 대상 노드로 이동할 때 떠나는 노드입니다.

li의 마우스아웃 이벤트 함수에서 reltg가 li의 하위 요소인 경우 관련 작업을 실행할 필요가 없습니다. reltg가 li의 상위 요소인 경우 관련 작업을 실행합니다.

다음 isMouseLeaveOrEnter 함수를 통해 li와 ​​reltg 사이의 포함 관계를 판단할 수 있습니다.

//判断事件相关元素与li的关系 如果事件相关元素为li的子元素就返回false 反之返回true
function isMouseLeaveOrEnter(e, handler) { 
  if (e.type != 'mouseout' && e.type != 'mouseover') return false; 
  var reltg = e.relatedTarget ? e.relatedTarget : e.type == 'mouseout' ? e.toElement : e.fromElement;
  while (reltg && reltg != handler) reltg = reltg.parentNode;
  return (reltg != handler);
};

Li.onmouseout = function(e) {
  e = e||window.event;
  if (isMouseLeaveOrEnter(e,this)) {
    //运行相关操作
  };
}

이 방법의 명백한 단점은 isMouseLeaveOrEnter에서 모든 상위 요소를 순회해야 한다는 것인데, 이는 성능 문제입니다.

해결책 3:

이 방법은 방법 2의 모든 상위 요소를 순회함으로써 발생하는 성능 문제를 최적화하는 li과 reltg 사이의 포함 관계를 결정하기 위해 비교DocumentPosition/contains를 사용한다는 점을 제외하면 방법 2와 아이디어가 동일합니다.

코드를 직접 살펴보겠습니다:

//判断node是否为parent的子元素
//if node == parent 也会返回true
function contains(parent, node) {
  if(parent.compareDocumentPosition){ //ff
    var _flag = parent.compareDocumentPosition(node); 
    return (_flag == 20 || _flag == 0)? true : false; 
  }else if(parent.contains){ //ie
    return parent.contains(node);
  }
};

Li.onmouseout = function(e) {
  e = e||window.event;
  var relatedEle = e.relatedTarget ? e.relatedTarget : e.type == 'mouseout' ? e.toElement : e.fromElement
  if (!contains(this, relatedEle)) {
    show.innerHTML=show.innerHTML+'0';
  }

}

compareDocumentPosition() 메서드는 두 노드를 비교하고 문서에서의 위치를 ​​설명하는 정수를 반환합니다.

반환 값은 다음과 같습니다.

1: 상관없습니다. 두 노드는 동일한 문서에 속하지 않습니다.

2: 첫 번째 노드(P1)는 두 번째 노드(P2) 뒤에 위치합니다.

4: 첫 번째 노드(P1)는 두 번째 노드(P2) 앞에 위치합니다.

8: 첫 번째 노드(P1)는 두 번째 노드(P2) 내에 위치합니다.

16: 두 번째 노드(P2)는 첫 번째 노드(P1) 내에 위치합니다.

32: 관계가 없거나 두 노드가 동일한 요소의 두 속성입니다.

참고: 반환 값은 값의 조합일 수 있습니다. 예를 들어, 20을 반환한다는 것은 p2가 p1(16) 내부에 있고 p1이 p2(4) 앞에 있음을 의미합니다.

그리고 [ie8-은 CompareDocumentPosition() 메서드를 지원하지 않습니다. 대신 containDocumentPosition() 메서드는 nodeB가 다른 nodeA에 포함되어 있는지 확인하는 데 사용됩니다. )

위 내용은 이 글의 전체 내용입니다. 모두 마음에 드셨으면 좋겠습니다.

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.