클릭 이벤트 델리게이션과 키보드 접근성

July 03, 2009 12:25 AM

네이버는 전사적으로 자바스크립트 개발과 사용의 효율성을 높이기 위해서 진도 프레임웍을 쓰고 있다. 오페라 미니에서 네이버의 페이지들이 정상적으로 작동하지 않는 것을 발견하고 그 원인을 찾다보니 자바스크립트 이벤트의 사용이 독특한 것을 발견할 수 있었다. 듀트님과 같이 얘기해 본 내용을 정리해보니 진도 프레임웍은 이벤트 버블링을 사용해서 자바스크립트 이벤트를 다루고 있는 것 같다.

보통 자바스크립트 이벤트는 사용자가 액션을 직접 취하는 요소에 적용한다. 예를 들어서 레이어를 보이게 하고 싶다면 사용자가 클릭을 하는 A 요소에 온클릭 이벤트 핸들러를 할당하게 된다. 하지만 이때 발생하는 이벤트는 그 요소에만 제한적이지 않다. 브라우저에 따라서 다르기는 하지만 보통 이벤트 버블링이나 이벤트 캡춰링을 통해서 다른 상위요소에서도 이벤트가 발생하게 된다. 클릭된 요소의 상위요소로 이벤트가 버블링을 통해서 번지게 되고 이를 이용해서 이벤트 발생을 제어할 수 있다. 네이버 뿐만아니라 요즘 이러한 방식을 사용하는 사이트가 조금씩 나오고 있는 것 같다.

진도에서는 이벤트를 이벤트가 발생되어야 하는 각 요소에 할당하지 않고 요소들을 감싸고 있는 상위 요소 - 보통은 DIV나 P요소 - 에 할당한다. 그러면 이벤트가 발생했을 때 이 상위 요소에서 이벤트를 제어할 수 있다.

문제는 이벤트가 발생해야 하는 요소가 아닌 상위 요소에 이벤트를 지정할 경우 이것이 키보드 접근성을 해치게 된다는 것이다. 오페라는 스페이셜 네비게이션(spatial navigation)이라는 키보드 접근 방법을 제공하고 있다. 스페이셜 네비게이션을 사용하면 상위 요소에 할당된 이벤트에도 접근이 가능해져서 사용자의 혼란을 야기할 수 있다. 네이버 뉴스 같은 경우도 전체 콘텐츠 영역이 선택이 가능해지게 된다. 포커스는 생기지만 클릭이 되지 않는 현상은 분명 키보드 접근에 있어서는 장애요소이다. 네이버 뉴스 메인에서 콘텐츠 영역이 전체가 키보드 클릭 영역으로 선택되는 현상

또한 이러한 현상은 장치독립성이 아주 중요한 모바일 기기에서도 나타난다. 아이폰의 사파리나 오페라 모바일로 네이버 페이지를 사용하다보면 반응은 하지 않지만 넓게 나타나는 클릭영역을 볼 수 있다. 아이폰 사파리에서 네이버 메인 페이지의 뉴스캐스트 영역 전체가 클릭 영역으로 잡힘 이러한 현상은 오페라 미니와 같은 서버-클라이언트 기반의 브라우저에서는 불편함을 넘어서 사용자에게 직접적으로 손해가 생길 수도 있다. 오페라 미니에서 네이버 메인 상단 메뉴에 카페에 포커스를 맞추면 링크가 아닌 전체 바가 선택된 미니는 자바스크립트 엔진이 클라이언트에 없기 때문에 이벤트가 발생할 경우 서버에 이벤트 처리를 요청해야 한다. 사용자 입장에서는 아무 동작도 하지 않는 이벤트를 위해서 불필요한 데이터 트래픽 비용을 지불해야 하게 된다. 많은 모바일 기기에서 키패드로 웹페이지를 사용해야 하는데 이 경우에도 네비게이션에 방해가 되는 포커스가 많이 나타난다.

왜 이러한 방식을 사용하는지 정확한 원인을 모르기 때문에 무조건 잘못됐다고 말 할 수는 없다. 아마도 성능상 - 사실 성능을 위해서는 버블링을 다 없애는게 더 좋다. - 이나 유지관리상 이점이 있을것 같기는 하다. 하지만 키보드로 사용할 때에는 분명한 장애요소이기 때문에 그 효용성이 높다고 하더라도 이벤트 처리 방식에 대해서 다시 고민할 필요가 있어보인다. 장치독립적인 접근 방식을 취할때 가장 비슷한 것이 키보드 네비게이션이기 때문에 데스크탑을 제외한 많은 기기에서 이러한 현상이 나타날 것으로 생각된다. 다양한 환경에서도 잘 작동할 수 있는 좋은 웹사이트를 제작하기 위해서는 이러한 장치독립성도 같이 고려할 필요가 있다.

(본의 아니게 갑자기 네이버까 분위기의 글을 많이 쓰게 되는데 - 하나 더 있음;; - 나쁜 의도는 아니고 제일 많이 쓰다보니까 자꾸 보이는 것이니 이해해 주세요.)

제목, 내용 수정: 진도 프레임 웍의 문제라기 보다는 온클릭 이벤트에 이벤트 델리게이션(event delegation) 방식을 사용했을 때의 문제이기 때문에 제목을 바꿨습니다. 제가 지식이 짧아서 너무 네이버만 부각 시킨것 같네요. 댓글 주신 분들 감사합니다. 이것도 과유불급이라는 말을 생각나게 합니다. 이벤트 델리게이션의 장점이 분명히 있지만 너무 많이 과용하는 것은 좋지 않을 것 같습니다. 클릭 이벤트 보다는 오버나 아웃을 다룰때 쓰면 아주 좋을 것 같네요.

Comments

  • denz 2009-07-03 10:07

    진도 자체가 무조건 버블링을 사용하도록 되어 있는건 아닙니다.
    기본으로 지원하는 방법은 엘리먼트에 직접 바인딩하는 방식입니다.
    해당 엘리먼트에 직접 이벤트를 바인딩할 지 상위 엘리먼트에 통한 버블링 방식을
    사용할지는 각 개발자의 선택이죠. ^^

    " 사실 성능을 위해서는 버블링을 다 없애는게 더 좋다. "
    이 부분은 좀 의아한데요?
    좀 더 설명해 주시면 좋을 듯 합니다.
    제 경험상 그렇지 않아서요.. ^^;

    그리고 키보드 네비게이션은 생각지 못한 부분이네요.
    좀 더 공부해 봐야 겠습니다.

    예를 드신 부분들을 제가 만든거 아니지만 의견 감사합니다. ^^

  • 전용우 2009-07-03 10:07

    이벤트 버블링이 위와 같은 현상을 나타내는지 몰랐네요.^^

    다만 위에 내용은 이벤트 딜리게이션(http://www.nczonline.net/blog/2009/06/30/event-delegation-in-javascript/) 대한 문제 인것 같은데 다소 느낌이 진도 프레임워크가 키보드 접근성을 떨어 뜨리는 느낌 주는군요. :(

    좋은 정보 감사합니다.

  • Outsider 2009-07-03 11:07

    생각하지 못했던 저런 문제가 있군요.
    하지만 저건 접근성의 문제라기 보다는 오페라쪽의 스페셜네이게이션(오늘 처음알았습니다만)의 구현방식에 더 문제가 있는건 아닐까요?
    일반적인 웹브라우저의 키보드 접근성에는 문제가 없을것으로 생각되는데요.
    윗분께서 이벤트 델리게이션에 대한 링크를 주셨지만 예전에는 각 엘리먼트에 onclick 인라인이벤트를 주었던데 비해 요즘은 따로 JS를 분리하는 추세로 가고 있고 그렇게 하다보면 모든 엘리먼트에 대해서 따로 다 등록하고 관리하는 것이 큰 비용이 들기 때문에 버블링을 이용해서 상위에서 한꺼번에 제어하는게 더 편한부분이 있는것이 사실입니다.(트리메뉴같은 것이 대표적이죠) 실제로 이런방식에 대한 다양한 예제들이 나오고 있고요.
    그리고 트리메뉴같은 경우 예를 들면 각 트리에 onclick 이벤트 리스너를 수십개 등록하는 것 보다는 상위에서 하나로 제어하는게 메모리도 덜 먹는 것으로 알고 있습니다. 이벤트리스너를 많이 등록하면 메모리릭도 발생할 가능성이 높아지기 때문에요...

    어쨌든 좀 애매한 문제이긴 하군요.... 덕분에 새로운 걸 배워갑니다.

  • 신현석 2009-07-05 22:07

    denz님, 성능은 항상 양면성을 가지고 있는 것 같습니다. 링크된 글에도 있지만 너무나 DOM 트리가 복잡할 경우 버블링을 사용하면 성능이 떨어질 수 있으니 아주 꺼버리는게 좋은 경우도 있는것 같습니다.

    "Besides, if your document structure is very complex (lots of nested tables and such) you may save system resources by turning off bubbling."

    하지만 말씀하신대로 경우에 따라서 버블링을 잘 활용하면 성능 향상에 도움이 되는 경우도 분명히 있을 것 같네요.

  • denz 2009-07-27 23:07

    음 제가 알기로는 신현석님은 자바스크립트 개발자가 아닌걸로 알고 있습니다.

    그래선지 본문에 추가하신 내용과 코멘트를 보면 자바스크립트 개발을 하는 분이 아니라는게 확 티가 납니다. -.-;

    오버나 아웃의 경우에는 이벤트 버블링을 잘 사용하지 않습니다.
    오히려 클릭을 많이 사용합니다.
    ( 오버, 아웃과 클릭은 이벤트 발생 순서가 서로 다릅니다. )

    그리고 요즘 추세가 DOM 트리가 복잡하고 동적으로 변하기 때문에 이벤트 버블링을 활용하려는 겁니다.

    버블링을 이용한다고 해서 버블링을 끄지 않는게 아닙니다.

    영역을 한정해서 버블링을 사용하고 그 상위로는 버블링을 꺼버리는 형태가 되겠죠.

    버블링을 사용한다는 것에 대해서 전체적으로 잘 못 생각하고 계신 듯 합니다.

  • 신현석 2009-07-28 10:07

    제가 말하고자 하는 내용은 이벤트 델리게이션을 사용할 때 키보드 접근성 측면에서는 부작용이 생긴다는 것입니다.

    "모르면 그냥 쓰지말지… 끝까지 아는 척이냐… -.-" http://me2day.net/denzels/2009/07/27#23:13:26

    그리고 말씀하신대로 저는 자바스크립트 개발자는 아닙니다. 그렇다고 모르면 입닥치고 있어라식의 태도는 아주 불쾌하군요. 몰라도 자꾸 얘기하고 공부해야 알게 되는 거죠. 제가 인용한 말은 기초적인 내용이기는 하지만 PPK가 한 말입니다.

    같은 일하는 사이에서 서로 감정상하지 않게 얘기 했으면 좋겠습니다.

  • denz 2009-07-28 12:07

    제가 욱해서 글을 좀 x가지 없게 써버렸네요...

    지금 보면 별다른 내용도 아닌데... -.-;;

    아마 제가 스크립트 개발일을 하다보니 그랬던거 같습니다.

    기분 나쁘셨던 부분은 사과드립니다. ( _ _ )

    먼저 이벤트 델리게이션이 키보드 접근성 측면에 좋지 않다고 말씀하신 내용은 공감하고 유념해야 할 부분이라고 생각합니다.

    제가 코멘트르 단 내용은 글 말미에 언급하신 내용과 코멘트에 대한 내용입니다.

    지금 이야기하고 있는 버블링과 인용하신 PPK가 성능이슈로 버블링을 끄라고 한 얘기는 살짝 다른 얘기입니다.

    인용부분이 원 글에 있을때는 문제가 없지만 지금 상황에서 답변으로 인용하실 내용으로 적절하지 않습니다.

    게다가 대단히 그럴듯해 보이는 답변이라 더욱 적절치 않다고 생각합니다.

    제가 저부분에 대한 지식이 조금만 부족했다면 답변 주신 내용을 맹신했을 겁니다.

    그 부분에서 제가 좀 기분이 나빴던 듯 하네요...

    호의로 답변해주신 글인데 제가 좀 오버해 버렸습니다.

    다시 한번 사과드립니다. (_ _)

Post a comment

:

: 공개 되지 않습니다. Gravatar를 표시 합니다.

:

: HTML 태그를 사용할 수 없습니다.