搜尋

首頁  >  問答  >  主體

如何檢測元素外部的點擊?

<p>我有一些 HTML 選單,當使用者點擊這些選單的頭部時,我會完全顯示這些選單。我想當用戶在菜單區域之外單擊時隱藏這些元素。 </p> <p>使用 jQuery 可以實現這樣的功能嗎? </p> <pre class="brush:php;toolbar:false;">$("#menuscontainer").clickOutsideThisElement(function() { // Hide the menus });</pre> <p><br /></p>
P粉113938880P粉113938880461 天前480

全部回覆(2)我來回復

  • P粉212114661

    P粉2121146612023-08-24 12:19:34

    您可以偵聽document 上的click 事件,然後確保#menucontainer 不是被點擊元素的祖先或目標通過使用.closest()

    如果不是,則按一下的元素位於#menucontainer 之外,您可以安全地將其隱藏。

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

    編輯 – 2017 年 6 月 23 日

    如果您打算關閉選單並想要停止偵聽事件,您也可以在事件偵聽器之後進行清理。此函數將僅清理新建立的偵聽器,保留 document 上的任何其他點擊偵聽器。使用 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);
    }
    

    編輯 – 2018 年 11 月 3 日

    對於不想使用 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 
    

    注意: 這是基於 Alex 的評論,僅使用 !element.contains(event.target) 而不是 jQuery 部分。

    但是 element.closest() 現在也可在所有主要瀏覽器中使用(W3C 版本與 jQuery 版本略有不同)。 Polyfill 可以在這裡找到:Element.closest()

    編輯 – 2020-05-21

    如果您希望使用者能夠在元素內部點擊並拖曳,然後在元素外部釋放滑鼠,而不關閉元素:

    ...
          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()
            }
        }

    回覆
    0
  • P粉333186285

    P粉3331862852023-08-24 10:52:59

    將點選事件附加到關閉視窗的文檔正文。將單獨的點擊事件附加到容器,以停止傳播到文件正文。

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

    回覆
    0
  • 取消回覆