728x90

JavaScript child element mouseout 이슈

자바스크립트


자바스크립트에서 mouseover 또는 mouseout을 지정할 때 이벤트가 지정된 엘리먼트가 child element를 포함하고 있다면 문제가 발생합니다.

<div id="parent" onmouseover="MyFuncHover()" onmouseout="MyFuncOut()">
    <span id="child">Text</span>
</div>

<script type="text/javascript">
    function MyFuncHover() {
        // Here I have some code that makes the "child" visible
    }

    function MyFuncOut() {
        // Here I have some code that makes the "child" invisible again
    }
</script>

위 코드에서 MyFuncOut 함수의 호출은 div#parent 엘리먼트를 벗어났을 때 되어야 합니다. 하지만, span 태그로 마우스를 이동하면 MyFuncOut 함수가 호출됩니다.

이는 마우스가 span 엘리먼트를 가르킴으로서 div 엘리먼트를 벗어났다고 인식해서 발생하는 것이지만, 대부분의 경우에는 MyFuncOut 함수가 호출되지 않는 것을 바랄 것입니다.

이를 해결할 수 있는 방법은 다음과 같습니다.

해결법

pointer-events: none

<div id="parent" onmouseover="MyFuncHover()" onmouseout="MyFuncOut()">
    <span id="child">Text</span>
</div>

<style>
  #child {
    pointer-events: none;
  }
</style>

<script type="text/javascript">
    function MyFuncHover() {
        // Here I have some code that makes the "child" visible
    }

    function MyFuncOut() {
        // Here I have some code that makes the "child" invisible again
    }
</script>

첫 번째 방법은 child element에 pointer-events: none 스타일을 추가하는 것입니다.

  • 장점
    • 자바스크립트 코드를 작성하지 않아도 됩니다.
  • 단점
    • 포인터 이벤트 스타일 자체를 없애버리기 때문에 커서의 모양이 변경되는 pointer: cursor; css 역시 동작하지 않습니다.
    • IE 10 이하 버전의 브라우저에서는 동작하지 않습니다.

mouseleave event

<div id="parent" onmouseover="MyFuncHover()" onmouseleave="MyFuncOut()">
  <span id="child">Text</span>
</div>

<script type="text/javascript">
  function MyFuncHover() {
    // Here I have some code that makes the "child" visible
  }

  function MyFuncOut() {
    // Here I have some code that makes the "child" invisible again
    console.log('mouse out')
  }
</script>

두 번째 방법은 mouseleave 이벤트를 사용하는 것입니다.
mouseover, mouseoutmouseenter, mouseleave의 차이점은 자식 요소까지 인식하는가에 있습니다.

  • mouseover, mouseout 이벤트의 경우 자식 요소에 접근하고 벗어났을 때 역시 호출됩니다.
  • mouseenter, mouseleave 이벤트의 경우 자식 요소에 접근했을 때 호출되지 않습니다.

추가적으로 별다른 스크립트를 작성하지 않고 해결할 수 있습니다.

또 다른 해결법

위 문제에 대해 구글에 검색했을 때 mouseout이 호출되는 시점에 마우스가 가리키고 있는 element의 부모 element를 비교하거나, contains를 사용해 추가적으로 자바스크립트 코드를 작성해서 해결하는 방법도 존재합니다.

다만, mouseleave 이벤트를 사용하면 추가적인 자바스크립트 코드(부모 엘리먼트를 비교하는..)를 작성하지 않고도 해결할 수 있어서 mouseleave 이벤트를 사용하는 것이 가장 효율적인 방법이 아닐까 생각됩니다.

728x90
728x90