복붙노트

[JQUERY] 어떻게 요소 외부의 클릭을 감지합니까?

JQUERY

어떻게 요소 외부의 클릭을 감지합니까?

해결법


  1. 1.창을 닫 문서 본문에 클릭 이벤트를 붙이는 것. 문서 본문에 전파를 중지 컨테이너에 별도의 클릭 이벤트를 연결합니다.

    창을 닫 문서 본문에 클릭 이벤트를 붙이는 것. 문서 본문에 전파를 중지 컨테이너에 별도의 클릭 이벤트를 연결합니다.

    $(window).click(function() {
    //Hide the menus if visible
    });
    
    $('#menucontainer').click(function(event){
        event.stopPropagation();
    });
    

  2. 2.당신은 문서에 클릭 이벤트를 수신하고 있는지 #menucontainer는 조상 또는 .closest를 사용하여 클릭 된 요소의 대상 ()하지 않습니다 수 있습니다.

    당신은 문서에 클릭 이벤트를 수신하고 있는지 #menucontainer는 조상 또는 .closest를 사용하여 클릭 된 요소의 대상 ()하지 않습니다 수 있습니다.

    그렇지 않은 경우, 클릭 된 요소는 외부 #menucontainer의 그리고 당신은 안전하게 숨길 수 있습니다.

    $(document).click(function(event) { 
      var $target = $(event.target);
      if(!$target.closest('#menucontainer').length && 
      $('#menucontainer').is(":visible")) {
        $('#menucontainer').hide();
      }        
    });
    

    당신이 메뉴를 닫 계획하고 이벤트를 수신 중지 할 경우에도 이벤트 리스너 뒤처리를 할 수 있습니다. 이 기능은 문서의 다른 클릭 리스너를 보존 만 새로 만든 수신기를 정리합니다. ES2015 구문 :

    export function hideOnClickOutside(selector) {
      const outsideClickListener = (event) => {
        const $target = $(event.target);
        if (!$target.closest(selector).length && $(selector).is(':visible')) {
            $(selector).hide();
            removeClickListener();
        }
      }
    
      const removeClickListener = () => {
        document.removeEventListener('click', outsideClickListener)
      }
    
      document.addEventListener('click', outsideClickListener)
    }
    

    jQuery를 사용하지 않는 사람들을 위해. 여기에 일반 vanillaJS (ECMAScript6)에서 위의 코드입니다.

    function hideOnClickOutside(element) {
        const outsideClickListener = event => {
            if (!element.contains(event.target) && isVisible(element)) { // or use: event.target.closest(selector) === null
              element.style.display = 'none'
              removeClickListener()
            }
        }
    
        const removeClickListener = () => {
            document.removeEventListener('click', outsideClickListener)
        }
    
        document.addEventListener('click', outsideClickListener)
    }
    
    const isVisible = elem => !!elem && !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ) // source (2018-03-11): https://github.com/jquery/jquery/blob/master/src/css/hiddenVisibleSelectors.js 
    

    노트: 이것은 단지 사용에 알렉스의 의견을 기반으로! element.contains (event.target) 대신 jQuery를 부분입니다.

    그러나 () 이제 모든 주요 브라우저 형태로도 주문 가능합니다 element.closest (W3C의 버전은 jQuery를 하나에서 약간 다릅니다). Polyfills는 여기에서 찾을 수 있습니다 : Element.closest ()

    당신은 사용자가 요소를 닫지 않고, 요소 외부에 마우스를 다음 요소 내부 및 드래그를 클릭하여 해제 할 수 있도록하려는 경우 :

          ...
          let lastMouseDownX = 0;
          let lastMouseDownY = 0;
          let lastMouseDownWasOutside = false;
    
          const mouseDownListener = (event: MouseEvent) => {
            lastMouseDownX = event.offsetX
            lastMouseDownY = event.offsetY
            lastMouseDownWasOutside = !$(event.target).closest(element).length
          }
          document.addEventListener('mousedown', mouseDownListener);
    

    그리고 outsideClickListener에서 :

    const outsideClickListener = event => {
            const deltaX = event.offsetX - lastMouseDownX
            const deltaY = event.offsetY - lastMouseDownY
            const distSq = (deltaX * deltaX) + (deltaY * deltaY)
            const isDrag = distSq > 3
            const isDragException = isDrag && !lastMouseDownWasOutside
    
            if (!element.contains(event.target) && isVisible(element) && !isDragException) { // or use: event.target.closest(selector) === null
              element.style.display = 'none'
              removeClickListener()
              document.removeEventListener('mousedown', mouseDownListener); // Or add this line to removeClickListener()
            }
        }
    

  3. 3.이 질문은 너무 인기가 많은 답을 가지고 이유는 믿을 수 없 복잡한 것입니다. 거의 팔년과 답변 수십 후, 나는 진정으로 접근성에 주어진 얼마나 작은 배려보고 놀라게하고있다.

    이 질문은 너무 인기가 많은 답을 가지고 이유는 믿을 수 없 복잡한 것입니다. 거의 팔년과 답변 수십 후, 나는 진정으로 접근성에 주어진 얼마나 작은 배려보고 놀라게하고있다.

    이 고귀한 원인과 실제 문제입니다. 질문 - 대부분의 답변을 시도 할 것으로 보인다 무엇의 제목 불행한 레드 헤링 (Red Herring)을 주소-이 포함되어 있습니다.

    힌트 :이 단어를 "클릭"입니다!

    당신이 대화 상자를 닫습니다 클릭 핸들러를 바인딩하는 경우, 당신은 이미 실패했습니다. 당신이 실패 한 이유는 모든 트리거 이벤트를 클릭하지 것입니다. 마우스를 사용하지 않는 사용자는 대화 상자를 탈출 할 수있을 것이다 (그리고 팝업 메뉴는 틀림없이 대화의 일종) 탭을 눌러, 그들은 그 이후에 클릭을 유발하지 않고 대화 뒤에 내용을 읽을 수 없습니다 행사.

    그럼 질문을 바꿔 보자.

    이 목표입니다. 불행하게도, 지금 우리는 userisfinishedwiththedialog 이벤트를 결합해야하고, 결합은 그렇게 간단하지입니다.

    그렇다면 우리는 사용자가 대화 상자를 사용하여 완료되었음을 감지 할 수 있습니까?

    좋은 시작은 포커스가 대화를 떠난 여부를 결정하는 것입니다.

    힌트 : 이벤트가 버블 링 단계에 바인딩 된 경우 blur 이벤트에주의, 흐림는 전파되지 않습니다!

    jQuery를가 잘 할 것입니다 대한 focusOut. 당신이 jQuery를 사용할 수없는 경우에, 당신은 캡처 단계에서 흐림 사용할 수 있습니다 :

    element.addEventListener('blur', ..., true);
    //                       use capture: ^^^^
    

    또한, 많은 대화를 위해 당신은 이득 ​​초점에 컨테이너를 허용해야합니다. 의 tabindex = 추가 "- 1"대화 상자가 그렇지 않으면 탭 이동의 흐름을 방해하지 않고 동적으로 포커스를받을 수 있도록.

    $ ( 'A').에 (, 기능을 '클릭'() { $ (this.hash) .toggleClass ( '활성') 초점 ().; }); $ ( 'DIV'). ( '대한 focusOut', 기능에 대한 () { $ (이) .removeClass ( '활성'); }); DIV { 표시 : 없음; } .active는 { 표시 : 블록; } <스크립트 SRC = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">

    로렘 입숨 슬픔 에는 AMET 앉아.

    두 개 이상의 분 동안 그 데모를 플레이하면 신속하게 문제를보고 시작해야합니다.

    첫 번째는 대화 상자에서 링크를 클릭 할 수없는 것입니다. 상호 작용이 발생하기 전에 대화 폐쇄로 이어질 것에 또는 탭을 클릭하려고. 내부 요소를 집중하는 것은 다시 focusIn 이벤트를 트리거하기 전에 대한 focusOut 이벤트를 트리거하기 때문이다.

    수정 이벤트 루프의 상태 변경을 대기하는 것이다. 이 작업은하지 지원 setImmediate을 브라우저 (...), 또는에서는 setTimeout (..., 0) setImmediate를 사용하여 수행 할 수 있습니다. 일단이 후속하는 focusIn 취소 할 수 있습니다 대기 :

    $('.submenu').on({
      focusout: function (e) {
        $(this).data('submenuTimer', setTimeout(function () {
          $(this).removeClass('submenu--active');
        }.bind(this), 0));
      },
      focusin: function (e) {
        clearTimeout($(this).data('submenuTimer'));
      }
    });
    

    $ ( 'A').에 (, 기능을 '클릭'() { $ (this.hash) .toggleClass ( '활성') 초점 ().; }); $ ( 'DIV').에 ({ 대한 focusOut : 함수 () { $ (이) .DATA ( '타이머'에서는 setTimeout (함수 () { $ (이) .removeClass ( '활성'); } .bind (이), 0)); }, 하는 focusIn : 함수 () { 사항 clearTimeout ($ (이) .DATA ( '타이머')); } }); DIV { 표시 : 없음; } .active는 { 표시 : 블록; } <스크립트 SRC = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">

    로렘 입숨 슬픔 에는 AMET 앉아.

    두 번째 문제는 대화가 링크를 다시 누르면되지 않습니다 닫을 때이다. 대화 상자가 링크를 클릭 다시 열 수있는 대화 상자를 트리거 후 닫기 동작을 트리거, 포커스를 잃고 있기 때문이다.

    이전 문제와 마찬가지로, 포커스 상태의 요구를 관리 할 수 ​​있습니다. 상태 변화가 이미 대기 된 것을 감안할 때, 그것은 대화 트리거에 포커스 이벤트를 처리 단지 문제 :

    $('a').on({
      focusout: function () {
        $(this.hash).data('timer', setTimeout(function () {
          $(this.hash).removeClass('active');
        }.bind(this), 0));
      },
      focusin: function () {
        clearTimeout($(this.hash).data('timer'));  
      }
    });
    

    $ ( 'A').에 (, 기능을 '클릭'() { $ (this.hash) .toggleClass ( '활성') 초점 ().; }); $ ( 'DIV').에 ({ 대한 focusOut : 함수 () { $ (이) .DATA ( '타이머'에서는 setTimeout (함수 () { $ (이) .removeClass ( '활성'); } .bind (이), 0)); }, 하는 focusIn : 함수 () { 사항 clearTimeout ($ (이) .DATA ( '타이머')); } }); $ ( 'A').에 ({ 대한 focusOut : 함수 () { $ (this.hash) .DATA ( '타이머'에서는 setTimeout (함수 () { $ (this.hash) .removeClass ( '활성'); } .bind (이), 0)); }, 하는 focusIn : 함수 () { 사항 clearTimeout ($ (this.hash) .DATA ( '타이머')); } }); DIV { 표시 : 없음; } .active는 { 표시 : 블록; } <스크립트 SRC = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">

    로렘 입숨 슬픔 에는 AMET 앉아.

    당신이 초점 상태를 처리하여 수행되었다 생각하면, 더는 사용자 경험을 단순화하기 위해이 할 수있는 것.

    이것은 종종 기능은 "가지고 좋은"입니다,하지만 당신은 어떤 종류의 모달 또는 팝업이 때의 일반적인 Esc 키를 그것을 닫을 것이라는 점을 것을.

    keydown: function (e) {
      if (e.which === 27) {
        $(this).removeClass('active');
        e.preventDefault();
      }
    }
    

    $ ( 'A').에 (, 기능을 '클릭'() { $ (this.hash) .toggleClass ( '활성') 초점 ().; }); $ ( 'DIV').에 ({ 대한 focusOut : 함수 () { $ (이) .DATA ( '타이머'에서는 setTimeout (함수 () { $ (이) .removeClass ( '활성'); } .bind (이), 0)); }, 하는 focusIn : 함수 () { 사항 clearTimeout ($ (이) .DATA ( '타이머')); }, 를 keyDown : 함수 (E) { 경우 (e.which === 27) { $ (이) .removeClass ( '활성'); e.preventDefault (); } } }); $ ( 'A').에 ({ 대한 focusOut : 함수 () { $ (this.hash) .DATA ( '타이머'에서는 setTimeout (함수 () { $ (this.hash) .removeClass ( '활성'); } .bind (이), 0)); }, 하는 focusIn : 함수 () { 사항 clearTimeout ($ (this.hash) .DATA ( '타이머')); } }); DIV { 표시 : 없음; } .active는 { 표시 : 블록; } <스크립트 SRC = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">

    로렘 입숨 슬픔 에는 AMET 앉아.

    당신은 당신이 대화 상자에서 포커스 요소가 알고 있다면, 당신은 직접 대화를 집중할 필요가 없습니다. 당신이 메뉴를 구축하는 경우, 대신 첫 번째 메뉴 항목을 집중할 수 있습니다.

    click: function (e) {
      $(this.hash)
        .toggleClass('submenu--active')
        .find('a:first')
        .focus();
      e.preventDefault();
    }
    

    $ ( '. menu__link').에 ({ 클릭 기능 (전자) { $ (this.hash) .toggleClass ( '메뉴 - 활성') .find ( 'A : 제') .초점(); e.preventDefault (); }, 대한 focusOut : 함수 () { $ (this.hash) .DATA ( 'submenuTimer'에서는 setTimeout (함수 () { - $ (this.hash) .removeClass ( '활성 메뉴') } .bind (이), 0)); }, 하는 focusIn : 함수 () { 사항 clearTimeout ($ (this.hash) .DATA ( 'submenuTimer')); } }); $ ( '. 하위 메뉴').에 ({ 대한 focusOut : 함수 () { $ (이) .DATA ( 'submenuTimer'에서는 setTimeout (함수 () { - $ (이) .removeClass ( '활성 메뉴') } .bind (이), 0)); }, 하는 focusIn : 함수 () { 사항 clearTimeout ($ (이) .DATA ( 'submenuTimer')); }, 를 keyDown : 함수 (E) { 경우 (e.which === 27) { - $ (이) .removeClass ( '활성 메뉴') e.preventDefault (); } } }); .menu { 목록 스타일 : 없음; 여백 : 0; 패딩 : 0; } .menu : 후 { 취소 : 둘 다; 내용 : ''; 표시 : 테이블; } .메뉴 아이템 { 왼쪽으로 뜨다; 위치 : 상대; } .menu__link { 배경 색상 : 연한 파랑; 검정색; 표시 : 블록; 패딩 : 0.5em 1em; 텍스트 장식 : 없음; } .menu__link : 호버, .menu__link : 초점 { 배경 색상 : 검정; 색상 : 연한 파랑; } .submenu { 국경 : 1 픽셀의 검은 색; 표시 : 없음; 왼쪽 : 0; 목록 스타일 : 없음; 여백 : 0; 패딩 : 0; 위치 : 절대; 상단 : 100 %; } .submenu - 활성 { 표시 : 블록; } .submenu__item { 폭 : 150 픽셀; } .submenu__link { 배경 색상 : 연한 파랑; 검정색; 표시 : 블록; 패딩 : 0.5em 1em; 텍스트 장식 : 없음; } .submenu__link : 호버, .submenu__link : 초점 { 배경 색상 : 검정; 색상 : 연한 파랑; } <스크립트 SRC = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">

      <리 클래스 = "menu__item"> 메뉴 1
        <리 클래스 = "submenu__item"> 예 1 <리 클래스 = "submenu__item"> 예 2 <리 클래스 = "submenu__item"> 예 3 <리 클래스 = "submenu__item"> 예 4 <리 클래스 = "menu__item"> 메뉴 2
          <리 클래스 = "submenu__item"> 예 1 <리 클래스 = "submenu__item"> 예 2 <리 클래스 = "submenu__item"> 예 3 <리 클래스 = "submenu__item"> 예 4 로렘 입숨 슬픔 에는 AMET 앉아.

          이 답변은 희망이 기능에 대한 접근 키보드와 마우스 지원의 기초를 다루고 있지만, 이미 꽤 상당한 규모의 나는 그러나 내가보기 엔 구현 세부 사항에 대한 사양을 참조하는 것이 좋습니다, WAI-ARIA 역할 및 속성의 논의를 피하기 위해거야 어떤 역할을 그들이 사용하고 다른 적절한 속성을해야한다.


        • 4.내가 사용했다, 그래서 여기에 다른 솔루션은 나를 위해 작동하지 않았다 :

          내가 사용했다, 그래서 여기에 다른 솔루션은 나를 위해 작동하지 않았다 :

          if(!$(event.target).is('#foo'))
          {
              // hide menu
          }
          

        • 5.내가 좀 이런 식으로 ... 메뉴를 열 때 나는 몸에 클릭 이벤트를 첨부 제외하고 나는,에 란의 예와 유사하게 작동하는 응용 프로그램이 있습니다 :

          내가 좀 이런 식으로 ... 메뉴를 열 때 나는 몸에 클릭 이벤트를 첨부 제외하고 나는,에 란의 예와 유사하게 작동하는 응용 프로그램이 있습니다 :

          $('#menucontainer').click(function(event) {
            $('html').one('click',function() {
              // Hide the menus
            });
          
            event.stopPropagation();
          });
          

          jQuery의 하나에 대한 자세한 정보 () 함수


        • 6.연구 후에 나는 세 가지 작업 솔루션을 (내가 참조 페이지 링크를 잊었) 발견

          연구 후에 나는 세 가지 작업 솔루션을 (내가 참조 페이지 링크를 잊었) 발견

          <script>
              //The good thing about this solution is it doesn't stop event propagation.
          
              var clickFlag = 0;
              $('body').on('click', function () {
                  if(clickFlag == 0) {
                      console.log('hide element here');
                      /* Hide element here */
                  }
                  else {
                      clickFlag=0;
                  }
              });
              $('body').on('click','#testDiv', function (event) {
                  clickFlag = 1;
                  console.log('showed the element');
                  /* Show the element */
              });
          </script>
          
          <script>
              $('body').on('click', function(e) {
                  if($(e.target).closest('#testDiv').length == 0) {
                     /* Hide dropdown here */
                  }
              });
          </script>
          
          <script>
              var specifiedElement = document.getElementById('testDiv');
              document.addEventListener('click', function(event) {
                  var isClickInside = specifiedElement.contains(event.target);
                  if (isClickInside) {
                    console.log('You clicked inside')
                  }
                  else {
                    console.log('You clicked outside')
                  }
              });
          </script>
          

        • 7.

          $("#menuscontainer").click(function() {
              $(this).focus();
          });
          $("#menuscontainer").blur(function(){
              $(this).hide();
          });
          

          잘 나를 위해 작동합니다.


        • 8.외부 이벤트 (블로그 게시물) : 지금 그것을위한 플러그인이있다

          외부 이벤트 (블로그 게시물) : 지금 그것을위한 플러그인이있다

          clickoutside 처리기 (WLOG가) 요소에 바인딩 할 때 다음과 같은 상황이 발생합니다

          어떤 이벤트가 전파에서 중단되지 않고 추가 클릭 핸들러는 외부 핸들러를 가진 요소 "위"사용할 수 있도록.


        • 9.이것은 완벽하게 나를 위해 일한!

          이것은 완벽하게 나를 위해 일한!

          $('html').click(function (e) {
              if (e.target.id == 'YOUR-DIV-ID') {
                  //do something
              } else {
                  //do something
              }
          });
          

        • 10.난 당신이 정말 필요 사용자가 외부를 클릭 할 때 메뉴를 닫 무엇인지 생각하지 않는다; 당신이 필요로하는 것은 가까이에 메뉴에 대한 때 사용자가 클릭 아무 곳이나 페이지의 모든시. 이 메뉴를 클릭하면, 또는 메뉴 떨어져 그것은 바로 닫아야?

          난 당신이 정말 필요 사용자가 외부를 클릭 할 때 메뉴를 닫 무엇인지 생각하지 않는다; 당신이 필요로하는 것은 가까이에 메뉴에 대한 때 사용자가 클릭 아무 곳이나 페이지의 모든시. 이 메뉴를 클릭하면, 또는 메뉴 떨어져 그것은 바로 닫아야?

          다른 일 게시물이 블로그를 작성하는 저를 묻는 메시지가보다 만족스러운 답을 찾기가 없습니다. 더 현학적를 들어,의 메모를 취할 개는 여러 가지가 있습니다 :


        • 11.또 다른 포스터는 개는 많은 당신이 (이 경우 메뉴에서)를 표시하는 요소가 상호 작용하는 요소가 특히가 말했듯이. 나는 매우 견고 다음 방법을 발견했습니다 :

          또 다른 포스터는 개는 많은 당신이 (이 경우 메뉴에서)를 표시하는 요소가 상호 작용하는 요소가 특히가 말했듯이. 나는 매우 견고 다음 방법을 발견했습니다 :

          $('#menuscontainer').click(function(event) {
              //your code that shows the menus fully
          
              //now set up an event listener so that clicking anywhere outside will close the menu
              $('html').click(function(event) {
                  //check up the tree of the click target to check whether user has clicked outside of menu
                  if ($(event.target).parents('#menuscontainer').length==0) {
                      // your code to hide menu
          
                      //this event listener has done its job so we can unbind it.
                      $(this).unbind(event);
                  }
          
              })
          });
          

        • 12.상황에 대한 간단한 솔루션입니다 :

          상황에 대한 간단한 솔루션입니다 :

          $(document).mouseup(function (e)
          {
              var container = $("YOUR SELECTOR"); // Give you class or ID
          
              if (!container.is(e.target) &&            // If the target of the click is not the desired div or section
                  container.has(e.target).length === 0) // ... nor a descendant-child of the container
              {
                  container.hide();
              }
          });
          

          사업부 클릭 이벤트의 외부가 트리거 될 경우에는, 위의 스크립트는 DIV를 숨 깁니다.

          http://www.codecanal.com/detect-click-outside-div-using-javascript/ : 당신은 자세한 내용은 다음 블로그를 볼 수 있습니다


        • 13.창 클릭 이벤트 대상 확인 (그것이이 다른 곳 캡처되지 것만큼, 윈도우에 전파한다), 그리고 메뉴 요소의 아니다 있는지 확인합니다. 그렇지 않은 경우에, 당신은 당신의 메뉴 외부입니다.

          창 클릭 이벤트 대상 확인 (그것이이 다른 곳 캡처되지 것만큼, 윈도우에 전파한다), 그리고 메뉴 요소의 아니다 있는지 확인합니다. 그렇지 않은 경우에, 당신은 당신의 메뉴 외부입니다.

          또는 클릭의 위치를 ​​확인하고,이 메뉴 곳에있는 경우를 참조하십시오.


        • 14.대신에 영향을 미치는 몇 가지 측면을 가질 수 있습니다 event.stopPropagation ()를 사용하는, 단순한 플래그 변수를 정의하고 조건이있는 경우 하나를 추가 할 수 있습니다. 나는 이것을 테스트 인 stopPropagation의 영향 어떤 측면없이 제대로 일 :

          대신에 영향을 미치는 몇 가지 측면을 가질 수 있습니다 event.stopPropagation ()를 사용하는, 단순한 플래그 변수를 정의하고 조건이있는 경우 하나를 추가 할 수 있습니다. 나는 이것을 테스트 인 stopPropagation의 영향 어떤 측면없이 제대로 일 :

          var flag = "1";
          $('#menucontainer').click(function(event){
              flag = "0"; // flag 0 means click happened in the area where we should not do any action
          });
          
          $('html').click(function() {
              if(flag != "0"){
                  // Hide the menus if visible
              }
              else {
                  flag = "1";
              }
          });
          

          단순한 조건의 경우와 :

          $(document).on('click', function(event){
              var container = $("#menucontainer");
              if (!container.is(event.target) &&            // If the target of the click isn't the container...
                  container.has(event.target).length === 0) // ... nor a descendant of the container
              {
                  // Do whatever you want to do when click is outside the element
              }
          });
          

        • 15.나는이 같은 성공을 했어 :

          나는이 같은 성공을 했어 :

          var $menuscontainer = ...;
          
          $('#trigger').click(function() {
            $menuscontainer.show();
          
            $('body').click(function(event) {
              var $target = $(event.target);
          
              if ($target.parents('#menuscontainer').length == 0) {
                $menuscontainer.hide();
              }
            });
          });
          

          #menuscontainer이 표시 될 때, 결합이 수피 (클릭의) 대상이 그 자식이 아닌 경우에만 #menuscontainer하는 본체 클릭 핸들러 : 논리이다.


        • 16.변형으로 :

          변형으로 :

          var $menu = $('#menucontainer');
          $(document).on('click', function (e) {
          
              // If element is opened and click target is outside it, hide it
              if ($menu.is(':visible') && !$menu.is(e.target) && !$menu.has(e.target).length) {
                  $menu.hide();
              }
          });
          

          이 이벤트 전파하고 더 나은 지원하는 처음 인 stopPropagation 솔루션에서 처음으로 열린 상태로됩니다 열려있는 동안 두 번째 메뉴를 클릭 한 페이지에 여러 개의 메뉴를 정지 아무 문제가 없습니다.


        • 17.이벤트는 "나무 위해 모든 조상의 정적 정렬 된 목록"입니다 요소의 event.path라는 속성이 있습니다. 이벤트가 특정의 DOM 요소 또는 그 자식 중 하나에서 유래 경우 단지 특정의 DOM 요소에 대한 경로를 확인, 확인하십시오. 또한 논리적으로 어떤 기능 요소의 검사를 논리합 연산하여 복수의 요소를 확인하기 위해 사용될 수있다.

          이벤트는 "나무 위해 모든 조상의 정적 정렬 된 목록"입니다 요소의 event.path라는 속성이 있습니다. 이벤트가 특정의 DOM 요소 또는 그 자식 중 하나에서 유래 경우 단지 특정의 DOM 요소에 대한 경로를 확인, 확인하십시오. 또한 논리적으로 어떤 기능 요소의 검사를 논리합 연산하여 복수의 요소를 확인하기 위해 사용될 수있다.

          $ ( "몸"). ((클릭 기능) { 타겟 = document.getElementById를 ( "메인"); 플래그 event.path.some (함수 (EL, I, 도착을) {= 창 (EL == 타겟) }) 경우 (플래그) { CONSOLE.LOG ( "내부") } 다른 { 을 console.log ( "외부") } }); #main { 표시 : 인라인 블록; 배경 : 노란색; } <스크립트 SRC = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">

          • 테스트 - 홈페이지
          • 테스트 - 홈페이지
          • 테스트 - 홈페이지
          • 테스트 - 홈페이지
          • 테스트 - 홈페이지 외부 홈페이지

            따라서 귀하의 경우에 그것은해야한다

            $("body").click(function() {
              target = $("#menuscontainer")[0];
              flag = event.path.some(function(el, i, arr) {
                return (el == target)
              });
              if (!flag) {
                // Hide the menus
              }
            });
            

          • 18.실제로 이벤트 대한 focusOut 인정 놀라지 누구도 생각하지 :

            실제로 이벤트 대한 focusOut 인정 놀라지 누구도 생각하지 :

            VAR = document.getElementById를 버튼 (버튼 '); button.addEventListener ({), 기능 (예 '를 클릭' e.target.style.backgroundColor = '녹색'; }); button.addEventListener ( '대한 focusOut ", 기능 (E) { e.target.style.backgroundColor = ""; }); <메타 캐릭터 = "UTF-8"> <버튼 ID는 = "버튼"> 를 클릭


          • 19.좀 jQuery를 일정 플러그인에서이 방법을 발견했다.

            좀 jQuery를 일정 플러그인에서이 방법을 발견했다.

            function ClickOutsideCheck(e)
            {
              var el = e.target;
              var popup = $('.popup:visible')[0];
              if (popup==undefined)
                return true;
            
              while (true){
                if (el == popup ) {
                  return true;
                } else if (el == document) {
                  $(".popup").hide();
                  return false;
                } else {
                  el = $(el).parent()[0];
                }
              }
            };
            
            $(document).bind('mousedown.popup', ClickOutsideCheck);
            

          • 20.여기에 미래의 시청자에 대한 바닐라 자바 ​​스크립트 솔루션입니다.

            여기에 미래의 시청자에 대한 바닐라 자바 ​​스크립트 솔루션입니다.

            클릭 된 요소의 ID가 교체 또는 숨겨진 요소가 숨겨져되지 않고 숨겨진 요소가 요소 토글, 클릭 된 요소를 포함하지 않는 경우, 문서 내의 모든 요소를 ​​클릭하면.

            (function () {
                "use strict";
                var hidden = document.getElementById('hidden');
                document.addEventListener('click', function (e) {
                    if (e.target.id == 'toggle' || (hidden.style.display != 'none' && !hidden.contains(e.target))) hidden.style.display = hidden.style.display == 'none' ? 'block' : 'none';
                }, false);
            })();
            

            (함수 () { "엄격한 사용"; VAR 숨겨진 = document.getElementById를 ( '숨겨진'); document.addEventListener ({), 기능 (예 '를 클릭' 경우 (e.target.id == '토글'|| (hidden.style.display! = '없음'&&! hidden.contains (e.target))) hidden.style.display = hidden.style.display == '없음'? '막지' '없음'; } 거짓); }) (); 전환 숨겨진 사업부

            이 콘텐츠가 정상적으로 표시되지 않습니다. 나 사라지게이 내용보다 아무 곳이나 클릭

            같은 페이지에 여러 토글을하려고하는 경우는 다음과 같이 사용할 수 있습니다 :

            (함수 () { "엄격한 사용"; var에 hiddenItems = document.getElementsByClassName ( '숨겨진'), 숨겨진; document.addEventListener ({), 기능 (예 '를 클릭' 위한 VAR (I = 0; I = 숨겨진 hiddenItems; I ++) { 만약 (! hidden.contains (e.target) && hidden.style.display! = '없음') hidden.style.display = '없음'; } 경우 (e.target.getAttribute ( '데이터 토글')) { VAR 토글 = document.querySelector (e.target.getAttribute ( '데이터 토글')); toggle.style.display = toggle.style.display == '없음'? '막지' '없음'; } } 거짓); }) (); 전환 숨겨진 사업부

            이 콘텐츠는 일반적으로 숨겨져> = "true"로 데이터가 숨겨진 전환 숨겨진 사업부
            이 콘텐츠는 일반적으로 숨겨져> = "true"로 데이터가 숨겨진 전환 숨겨진 사업부
            이 콘텐츠는 일반적으로 숨겨져> = "true"로 데이터가 숨겨진


          • 21.당신이 IE와 FF 3 *에 대한 스크립팅하고 그냥 클릭이 특정 박스 영역 내에서 발생하는 경우 알고 싶은 경우에, 당신은 또한 같은 것을 사용할 수 있습니다 :

            당신이 IE와 FF 3 *에 대한 스크립팅하고 그냥 클릭이 특정 박스 영역 내에서 발생하는 경우 알고 싶은 경우에, 당신은 또한 같은 것을 사용할 수 있습니다 :

            this.outsideElementClick = function(objEvent, objElement){   
            var objCurrentElement = objEvent.target || objEvent.srcElement;
            var blnInsideX = false;
            var blnInsideY = false;
            
            if (objCurrentElement.getBoundingClientRect().left >= objElement.getBoundingClientRect().left && objCurrentElement.getBoundingClientRect().right <= objElement.getBoundingClientRect().right)
                blnInsideX = true;
            
            if (objCurrentElement.getBoundingClientRect().top >= objElement.getBoundingClientRect().top && objCurrentElement.getBoundingClientRect().bottom <= objElement.getBoundingClientRect().bottom)
                blnInsideY = true;
            
            if (blnInsideX && blnInsideY)
                return false;
            else
                return true;}
            

          • 22.대신 흐름 중단, 흐림 / 포커스 이벤트 또는 기타 까다로운 공예를 사용하여, 단순히 요소의 친족 관계와 이벤트 흐름을 일치 :

            대신 흐름 중단, 흐림 / 포커스 이벤트 또는 기타 까다로운 공예를 사용하여, 단순히 요소의 친족 관계와 이벤트 흐름을 일치 :

            $(document).on("click.menu-outside", function(event){
                // Test if target and it's parent aren't #menuscontainer
                // That means the click event occur on other branch of document tree
                if(!$(event.target).parents().andSelf().is("#menuscontainer")){
                    // Click outisde #menuscontainer
                    // Hide the menus (but test if menus aren't already hidden)
                }
            });
            

            단순히 외부 이벤트 리스너를 클릭 제거하려면 :

            $(document).off("click.menu-outside");
            

          • 23.사용하다:

            사용하다:

            var go = false;
            $(document).click(function(){
                if(go){
                    $('#divID').hide();
                    go = false;
                }
            })
            
            $("#divID").mouseover(function(){
                go = false;
            });
            
            $("#divID").mouseout(function (){
                go = true;
            });
            
            $("btnID").click( function(){
                if($("#divID:visible").length==1)
                    $("#divID").hide(); // Toggle
                $("#divID").show();
            });
            

          • 24.여기에 호기심 누군가가 자바 스크립트 솔루션 (ES6)의 경우 :

            여기에 호기심 누군가가 자바 스크립트 솔루션 (ES6)의 경우 :

            window.addEventListener('mouseup', e => {
                    if (e.target != yourDiv && e.target.parentNode != yourDiv) {
                        yourDiv.classList.remove('show-menu');
                        //or yourDiv.style.display = 'none';
                    }
                })
            

            및 ES5, 단지 경우 :

            window.addEventListener('mouseup', function (e) {
            if (e.target != yourDiv && e.target.parentNode != yourDiv) {
                yourDiv.classList.remove('show-menu'); 
                //or yourDiv.style.display = 'none';
            }
            

            });


          • 25.여기에 순수 자바 스크립트로 간단한 솔루션입니다. 그것은 최신 상태 ES6에 있습니다 :

            여기에 순수 자바 스크립트로 간단한 솔루션입니다. 그것은 최신 상태 ES6에 있습니다 :

            var isMenuClick = false;
            var menu = document.getElementById('menuscontainer');
            document.addEventListener('click',()=>{
                if(!isMenuClick){
                   //Hide the menu here
                }
                //Reset isMenuClick 
                isMenuClick = false;
            })
            menu.addEventListener('click',()=>{
                isMenuClick = true;
            })
            

          • 26.나는 스크립트 아래 사용 및 jQuery를 함께 했어요.

            나는 스크립트 아래 사용 및 jQuery를 함께 했어요.

            jQuery(document).click(function(e) {
                var target = e.target; //target div recorded
                if (!jQuery(target).is('#tobehide') ) {
                    jQuery(this).fadeOut(); //if the click element is not the above id will hide
                }
            })
            

            아래는 HTML 코드를 찾을 수

            <div class="main-container">
            <div> Hello I am the title</div>
            <div class="tobehide">I will hide when you click outside of me</div>
            </div>
            

            여기 자습서를 읽을 수 있습니다


          • 27.

            $(document).click(function() {
                $(".overlay-window").hide();
            });
            $(".overlay-window").click(function() {
                return false;
            });
            

            문서를 클릭하면 해당 같은 요소를 클릭하지 않는 한, 지정된 요소를 숨 깁니다.


          • 28.문서에 클릭 이벤트 리스너를 후크. 이벤트 리스너 내부, 당신은 특히 event.target이 요소가 클릭 된 상황을 확인하기 위해 이벤트 객체 볼 수 있습니다 :

            문서에 클릭 이벤트 리스너를 후크. 이벤트 리스너 내부, 당신은 특히 event.target이 요소가 클릭 된 상황을 확인하기 위해 이벤트 객체 볼 수 있습니다 :

            $(document).click(function(e){
                if ($(e.target).closest("#menuscontainer").length == 0) {
                    // .closest can help you determine if the element 
                    // or one of its ancestors is #menuscontainer
                    console.log("hide");
                }
            });
            

          • 29.가장 인기있는 대답,하지만 추가에 대한 찬성 투표

            가장 인기있는 대답,하지만 추가에 대한 찬성 투표

            && (e.target != $('html').get(0)) // ignore the scrollbar
            

            그래서, 스크롤 막대에 클릭하지 [숨기기 또는 무엇이든] 대상 요소를 않습니다.


          • 30.쉽게 사용, 그리고 더 많은 표현 코드를 위해, 나는 이것에 대한 jQuery 플러그인을 만들어 :

            쉽게 사용, 그리고 더 많은 표현 코드를 위해, 나는 이것에 대한 jQuery 플러그인을 만들어 :

            $('div.my-element').clickOut(function(target) { 
                //do something here... 
            });
            

            참고 : 대상은 사용자가 실제로 클릭 한 요소이다. 당신이 jQuery를 콜백에서 예상대로 당신이 활용할 수 있도록 그러나 콜백은 여전히 ​​원래의 요소의 컨텍스트에서 실행됩니다.

            플러그인:

            $.fn.clickOut = function (parent, fn) {
                var context = this;
                fn = (typeof parent === 'function') ? parent : fn;
                parent = (parent instanceof jQuery) ? parent : $(document);
            
                context.each(function () {
                    var that = this;
                    parent.on('click', function (e) {
                        var clicked = $(e.target);
                        if (!clicked.is(that) && !clicked.parents().is(that)) {
                            if (typeof fn === 'function') {
                                fn.call(that, clicked);
                            }
                        }
                    });
            
                });
                return context;
            };
            

            기본적으로 클릭 이벤트 리스너는 문서에 배치됩니다. 당신이 이벤트 리스너의 범위를 제한하려는 경우, 당신은 클릭이 경청 될에서 상단의 부모가 될 것입니다 상위 레벨 요소를 나타내는 jQuery를 객체에 전달할 수 있습니다. 이 불필요한 문서 레벨의 이벤트 리스너를 방지 할 수 있습니다. 공급 부모 요소가 초기 요소의 부모가 아닌 분명히, 그것은 작동하지 않습니다.

            사용 같은 :

            $('div.my-element').clickOut($('div.my-parent'), function(target) { 
                //do something here...
            });
            

          from https://stackoverflow.com/questions/152975/how-do-i-detect-a-click-outside-an-element by cc-by-sa and MIT license