我有一些HTML菜单,当用户单击这些菜单的头部时,我会完全显示这些菜单。当用户在菜单区域外单击时,我希望隐藏这些元素。
jQuery是否可以实现这样的功能?
$("#menuscontainer").clickOutsideThisElement(function() {
// Hide the menus
});
我有一些HTML菜单,当用户单击这些菜单的头部时,我会完全显示这些菜单。当用户在菜单区域外单击时,我希望隐藏这些元素。
jQuery是否可以实现这样的功能?
$("#menuscontainer").clickOutsideThisElement(function() {
// Hide the menus
});
当前回答
为了更易于使用和表达代码,我为此创建了一个jQuery插件:
$('div.my-element').clickOut(function(target) {
//do something here...
});
注意:target是用户实际单击的元素。但回调仍然在原始元素的上下文中执行,所以您可以像在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...
});
其他回答
经过研究,我找到了三种可行的解决方案
第一种解决方案
<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>
投票选出最受欢迎的答案,但添加
&& (e.target != $('html').get(0)) // ignore the scrollbar
因此,单击滚动条不会隐藏目标元素。
我知道这个问题有一百万个答案,但我一直喜欢使用HTML和CSS来完成大部分工作。在这种情况下,z索引和定位。我找到的最简单的方法如下:
$(“#show trigger”).click(function(){$(“#element”).animate({width:'toggle'});$(“#外部元素”).show();});$(“#外部元素”).click(function(){$(“#element”).hide();$(“#外部元素”).hide();});#外部元件{位置:固定;宽度:100%;高度:100%;z指数:1;显示:无;}#元素{显示:无;填充:20px;背景色:#ccc;宽度:300px;z指数:2;位置:相对;}#显示触发器{填充:20px;背景色:#ccc;边距:20px自动;z指数:2;}<script src=“https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js“></script><div id=“outside element”></div><div id=“element”><div class=“menu item”><a href=“#1”>菜单项1</a></div><div class=“menu item”><a href=“#2”>菜单项1</a></div><div class=“menu item”><a href=“#3”>菜单项1</a></div><div class=“menu item”><a href=“#4”>菜单项1</a></div></div><div id=“show trigger”>显示菜单</div>
这创建了一个安全的环境,因为除非菜单实际打开,否则不会触发任何内容,并且z索引保护元素中的任何内容在被单击时不会产生任何错误。
此外,您不需要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>
你可以在这里阅读教程
$(document).on('click.menu.hide', function(e){
if ( !$(e.target).closest('#my_menu').length ) {
$('#my_menu').find('ul').toggleClass('active', false);
}
});
$(document).on('click.menu.show', '#my_menu li', function(e){
$(this).find('ul').toggleClass('active');
});
div {
float: left;
}
ul {
padding: 0;
position: relative;
}
ul li {
padding: 5px 25px 5px 10px;
border: 1px solid silver;
cursor: pointer;
list-style: none;
margin-top: -1px;
white-space: nowrap;
}
ul li ul:before {
margin-right: -20px;
position: absolute;
top: -17px;
right: 0;
content: "\25BC";
}
ul li ul li {
visibility: hidden;
height: 0;
padding-top: 0;
padding-bottom: 0;
border-width: 0 0 1px 0;
}
ul li ul li:last-child {
border: none;
}
ul li ul.active:before {
content: "\25B2";
}
ul li ul.active li {
display: list-item;
visibility: visible;
height: inherit;
padding: 5px 25px 5px 10px;
}
<script src="https://code.jquery.com/jquery-2.1.4.js"></script>
<div>
<ul id="my_menu">
<li>Menu 1
<ul>
<li>subMenu 1</li>
<li>subMenu 2</li>
<li>subMenu 3</li>
<li>subMenu 4</li>
</ul>
</li>
<li>Menu 2
<ul>
<li>subMenu 1</li>
<li>subMenu 2</li>
<li>subMenu 3</li>
<li>subMenu 4</li>
</ul>
</li>
<li>Menu 3</li>
<li>Menu 4</li>
<li>Menu 5</li>
<li>Menu 6</li>
</ul>
</div>
这里是jsbin版本http://jsbin.com/xopacadeni/edit?html,css,js,输出