我有一些HTML菜单,当用户单击这些菜单的头部时,我会完全显示这些菜单。当用户在菜单区域外单击时,我希望隐藏这些元素。

jQuery是否可以实现这样的功能?

$("#menuscontainer").clickOutsideThisElement(function() {
    // Hide the menus
});

当前回答

这是我解决这个问题的方法:

$(document).ready(function() {
  $('#user-toggle').click(function(e) {
    $('#user-nav').toggle();
    e.stopPropagation();
  });

  $('body').click(function() {
    $('#user-nav').hide(); 
  });

  $('#user-nav').click(function(e){
    e.stopPropagation();
  });
});

其他回答

现在是2020年,您可以使用event.composedPath()

发件人:Event.composedPath()

Event接口的composedPath()方法返回事件的路径,该路径是将调用侦听器的对象数组。

const target=document.querySelector(“#myTarget”)document.addEventListener('click',(event)=>{const withinBoundaries=event.composedPath().includes(目标)if(边界内){target.innerText='单击发生在元素内部'}其他{target.innerText='单击发生**外部**元素'}})/*只是为了让它好看。你不需要这个*/#我的目标{边距:50px自动;宽度:500px;高度:500px;背景:灰色;边框:10px实心黑色;}<div id=“myTarget”>单击我(或不单击!)</div>

对于那些希望将一个简短的解决方案集成到JS代码中的人来说——一个没有JQuery的小型库:

用法:

// demo code
var htmlElem = document.getElementById('my-element')
function doSomething(){ console.log('outside click') }

// use the lib
var removeListener = new elemOutsideClickListener(htmlElem, doSomething);

// deregister on your wished event
$scope.$on('$destroy', removeListener);

下面是库:


function elemOutsideClickListener (element, outsideClickFunc, insideClickFunc) {
   function onClickOutside (e) {
      var targetEl = e.target; // clicked element
      do {
         // click inside
         if (targetEl === element) {
            if (insideClickFunc) insideClickFunc();
            return;

         // Go up the DOM
         } else {
            targetEl = targetEl.parentNode;
         }
      } while (targetEl);

      // click outside
      if (!targetEl && outsideClickFunc) outsideClickFunc();
   }

   window.addEventListener('click', onClickOutside);

   return function () {
      window.removeEventListener('click', onClickOutside);
   };
}

我从这里获取代码并将其放在函数中:https://www.w3docs.com/snippets/javascript/how-to-detect-a-click-outside-an-element.html

经过研究,我找到了三种可行的解决方案

第一种解决方案

<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>

用纯JavaScript编写的方法

let menu = document.getElementById("menu");

document.addEventListener("click", function(){
    // Hide the menus
    menu.style.display = "none";
}, false);

document.getElementById("menuscontainer").addEventListener("click", function(e){
    // Show the menus
    menu.style.display = "block";
    e.stopPropagation();
}, false);

对于某些人来说,这可能是一个更好的解决方案。

$(".menu_link").click(function(){
    // show menu code
});

$(".menu_link").mouseleave(function(){
    //hide menu code, you may add a timer for 3 seconds before code to be run
});

我知道mouseleave不仅意味着在外面单击,还意味着离开该元素的区域。

一旦菜单本身位于menu_link元素内,那么单击或移动菜单本身应该不会有问题。