Ser*_*Amo 2367 javascript jquery
我有一些HTML菜单,当用户点击这些菜单的头部时,我会完全显示.当用户点击菜单区域外时,我想隐藏这些元素.
jQuery可以这样吗?
$("#menuscontainer").clickOutsideThisElement(function() {
// Hide the menus
});
Run Code Online (Sandbox Code Playgroud)
Era*_*rin 1763
注意:使用
stopEventPropagation()是应该避免的,因为它破坏了DOM中的正常事件流.有关更多信息,请参阅此文章.考虑使用这种方法,而不是
将单击事件附加到关闭窗口的文档正文.将单独的单击事件附加到容器,该容器将停止传播到文档正文.
$(window).click(function() {
//Hide the menus if visible
});
$('#menucontainer').click(function(event){
event.stopPropagation();
});
Run Code Online (Sandbox Code Playgroud)
Art*_*Art 1326
您可以侦听单击事件document,然后通过使用确保#menucontainer不是祖先或单击元素的目标 .closest().
如果不是,则单击的元素位于其外部,#menucontainer您可以安全地隐藏它.
$(document).click(function(event) {
$target = $(event.target);
if(!$target.closest('#menucontainer').length &&
$('#menucontainer').is(":visible")) {
$('#menucontainer').hide();
}
});
Run Code Online (Sandbox Code Playgroud)
如果您打算关闭菜单并想要停止侦听事件,也可以在事件监听器之后进行清理.此函数将仅清除新创建的侦听器,并保留其他任何单击侦听器document.使用ES2015语法:
export function hideOnClickOutside(selector) {
const outsideClickListener = (event) => {
$target = $(event.target);
if (!$target.closest(selector).length && $(selector).is(':visible')) {
$(selector).hide();
removeClickListener();
}
}
const removeClickListener = () => {
document.removeEventListener('click', outsideClickListener)
}
document.addEventListener('click', outsideClickListener)
}
Run Code Online (Sandbox Code Playgroud)
对于那些不想使用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
Run Code Online (Sandbox Code Playgroud)
注意:
这是基于Alex注释!element.contains(event.target)而不是使用jQuery部分.
但是element.closest()现在所有主流浏览器都可以使用(W3C版本与jQuery版本略有不同).Polyfills可以在这里找到:https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
zzz*_*Bov 277
如何检测元素外的点击?
这个问题如此受欢迎并且答案如此之多的原因在于它看起来很复杂.经过近八年的时间和几十个答案,我真的很惊讶地看到对可访问性的关注度很低.
当用户点击菜单区域外时,我想隐藏这些元素.
这是一个崇高的事业,也是实际问题.问题的标题 - 大多数答案似乎试图解决 - 包含一个不幸的红鲱鱼.
提示:这是"点击"这个词!
如果您绑定了点击处理程序以关闭对话框,那么您已经失败了.你失败的原因是不是每个人都会触发click事件.不使用鼠标的用户将能够通过按下来转义对话框(并且您的弹出菜单可以说是一种对话框)Tab,然后他们将无法在不随后触发click事件的情况下读取对话框后面的内容.
所以让我们重新解释一下这个问题.
当用户完成对话时,如何关闭对话框?
这是目标.不幸的是,现在我们需要绑定userisfinishedwiththedialog事件,并且绑定不是那么简单.
那么我们如何检测用户是否已完成对话框的使用?
focusout 事件一个好的开始是确定焦点是否已离开对话框.
提示:小心blur事件,blur如果事件被绑定到冒泡阶段,则不会传播!
jQuery focusout会做得很好.如果你不能使用jQuery,那么你可以blur在捕获阶段使用:
element.addEventListener('blur', ..., true);
// use capture: ^^^^
Run Code Online (Sandbox Code Playgroud)
此外,对于许多对话框,您需要允许容器获得焦点.添加tabindex="-1"以允许对话框动态接收焦点,而不会中断选项卡流.
$('a').on('click', function () {
$(this.hash).toggleClass('active').focus();
});
$('div').on('focusout', function () {
$(this).removeClass('active');
});Run Code Online (Sandbox Code Playgroud)
div {
display: none;
}
.active {
display: block;
}Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="#example">Example</a>
<div id="example" tabindex="-1">
Lorem ipsum <a href="http://example.com">dolor</a> sit amet.
</div>Run Code Online (Sandbox Code Playgroud)
如果您使用该演示超过一分钟,您应该很快就会看到问题.
第一个是对话框中的链接不可点击.尝试单击它或选项卡到它将导致对话关闭在交互发生之前.这是因为聚焦内部元素会focusout在focusin再次触发事件之前触发事件.
修复是在事件循环上对状态更改进行排队.这可以通过使用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'));
}
});
Run Code Online (Sandbox Code Playgroud)
$('a').on('click', function () {
$(this.hash).toggleClass('active').focus();
});
$('div').on({
focusout: function () {
$(this).data('timer', setTimeout(function () {
$(this).removeClass('active');
}.bind(this), 0));
},
focusin: function () {
clearTimeout($(this).data('timer'));
}
});Run Code Online (Sandbox Code Playgroud)
div {
display: none;
}
.active {
display: block;
}Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="#example">Example</a>
<div id="example" tabindex="-1">
Lorem ipsum <a href="http://example.com">dolor</a> sit amet.
</div>Run Code Online (Sandbox Code Playgroud)
第二个问题是再次按下链接时对话框不会关闭.这是因为对话框失去焦点,触发关闭行为,之后链接单击触发对话框重新打开.
与前一个问题类似,需要管理焦点状态.鉴于状态更改已经排队,只需在对话框触发器上处理焦点事件:
这应该看起来很熟悉$('a').on({
focusout: function () {
$(this.hash).data('timer', setTimeout(function () {
$(this.hash).removeClass('active');
}.bind(this), 0));
},
focusin: function () {
clearTimeout($(this.hash).data('timer'));
}
});
Run Code Online (Sandbox Code Playgroud)
$('a').on('click', function () {
$(this.hash).toggleClass('active').focus();
});
$('div').on({
focusout: function () {
$(this).data('timer', setTimeout(function () {
$(this).removeClass('active');
}.bind(this), 0));
},
focusin: function () {
clearTimeout($(this).data('timer'));
}
});
$('a').on({
focusout: function () {
$(this.hash).data('timer', setTimeout(function () {
$(this.hash).removeClass('active');
}.bind(this), 0));
},
focusin: function () {
clearTimeout($(this.hash).data('timer'));
}
});Run Code Online (Sandbox Code Playgroud)
div {
display: none;
}
.active {
display: block;
}Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="#example">Example</a>
<div id="example" tabindex="-1">
Lorem ipsum <a href="http://example.com">dolor</a> sit amet.
</div>Run Code Online (Sandbox Code Playgroud)
如果您认为自己是通过处理焦点状态来完成的,那么您可以采取更多措施来简化用户体验.
这通常是一个"很好的"功能,但是当你有一个任何类型的模态或弹出Esc键时,键会关闭它是很常见的.
keydown: function (e) {
if (e.which === 27) {
$(this).removeClass('active');
e.preventDefault();
}
}
Run Code Online (Sandbox Code Playgroud)
$('a').on('click', function () {
$(this.hash).toggleClass('active').focus();
});
$('div').on({
focusout: function () {
$(this).data('timer', setTimeout(function () {
$(this).removeClass('active');
}.bind(this), 0));
},
focusin: function () {
clearTimeout($(this).data('timer'));
},
keydown: function (e) {
if (e.which === 27) {
$(this).removeClass('active');
e.preventDefault();
}
}
});
$('a').on({
focusout: function () {
$(this.hash).data('timer', setTimeout(function () {
$(this.hash).removeClass('active');
}.bind(this), 0));
},
focusin: function () {
clearTimeout($(this.hash).data('timer'));
}
});Run Code Online (Sandbox Code Playgroud)
div {
display: none;
}
.active {
display: block;
}Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="#example">Example</a>
<div id="example" tabindex="-1">
Lorem ipsum <a href="http://example.com">dolor</a> sit amet.
</div>Run Code Online (Sandbox Code Playgroud)
如果您知道对话框中有可聚焦元素,则无需直接聚焦对话框.如果您正在构建菜单,则可以改为聚焦第一个菜单项.
click: function (e) {
$(this.hash)
.toggleClass('submenu--active')
.find('a:first')
.focus();
e.preventDefault();
}
Run Code Online (Sandbox Code Playgroud)
$('.menu__link').on({
click: function (e) {
$(this.hash)
.toggleClass('submenu--active')
.find('a:first')
.focus();
e.preventDefault();
},
focusout: function () {
$(this.hash).data('submenuTimer', setTimeout(function () {
$(this.hash).removeClass('submenu--active');
}.bind(this), 0));
},
focusin: function () {
clearTimeout($(this.hash).data('submenuTimer'));
}
});
$('.submenu').on({
focusout: function () {
$(this).data('submenuTimer', setTimeout(function () {
$(this).removeClass('submenu--active');
}.bind(this), 0));
},
focusin: function () {
clearTimeout($(this).data('submenuTimer'));
},
keydown: function (e) {
if (e.which === 27) {
$(this).removeClass('submenu--active');
e.preventDefault();
}
}
});Run Code Online (Sandbox Code Playgroud)
.menu {
list-style: none;
margin: 0;
padding: 0;
}
.menu:after {
clear: both;
content: '';
display: table;
}
.menu__item {
float: left;
position: relative;
}
.menu__link {
background-color: lightblue;
color: black;
display: block;
padding: 0.5em 1em;
text-decoration: none;
}
.menu__link:hover,
.menu__link:focus {
background-color: black;
color: lightblue;
}
.submenu {
border: 1px solid black;
display: none;
left: 0;
list-style: none;
margin: 0;
padding: 0;
position: absolute;
top: 100%;
}
.submenu--active {
display: block;
}
.submenu__item {
width: 150px;
}
.submenu__link {
background-color: lightblue;
color: black;
display: block;
padding: 0.5em 1em;
text-decoration: none;
}
.submenu__link:hover,
.submenu__link:focus {
background-color: black;
color: lightblue;
}Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="menu">
<li class="menu__item">
<a class="menu__link" href="#menu-1">Menu 1</a>
<ul class="submenu" id="menu-1" tabindex="-1">
<li class="submenu__item"><a class="submenu__link" href="http://example.com/#1">Example 1</a></li>
<li class="submenu__item"><a class="submenu__link" href="http://example.com/#2">Example 2</a></li>
<li class="submenu__item"><a class="submenu__link" href="http://example.com/#3">Example 3</a></li>
<li class="submenu__item"><a class="submenu__link" href="http://example.com/#4">Example 4</a></li>
</ul>
</li>
<li class="menu__item">
<a class="menu__link" href="#menu-2">Menu 2</a>
<ul class="submenu" id="menu-2" tabindex="-1">
<li class="submenu__item"><a class="submenu__link" href="http://example.com/#1">Example 1</a></li>
<li class="submenu__item"><a class="submenu__link" href="http://example.com/#2">Example 2</a></li>
<li class="submenu__item"><a class="submenu__link" href="http://example.com/#3">Example 3</a></li>
<li class="submenu__item"><a class="submenu__link" href="http://example.com/#4">Example 4</a></li>
</ul>
</li>
</ul>
lorem ipsum <a href="http://example.com/">dolor</a> sit amet.Run Code Online (Sandbox Code Playgroud)
这个答案有希望涵盖这个功能的可访问键盘和鼠标支持的基础知识,但由于它已经相当大,我将避免任何关于WAI-ARIA角色和属性的讨论,但我强烈建议实施者参考规范了解详情他们应该使用什么角色以及任何其他适当的属性.
Den*_*nis 139
这里的其他解决方案对我不起作用,所以我不得不使用:
if(!$(event.target).is('#foo'))
{
// hide menu
}
Run Code Online (Sandbox Code Playgroud)
Joe*_*oni 126
我有一个与Eran的例子类似的应用程序,除了我打开菜单时将click事件附加到正文...有点像这样:
$('#menucontainer').click(function(event) {
$('html').one('click',function() {
// Hide the menus
});
event.stopPropagation();
});
Run Code Online (Sandbox Code Playgroud)
Cez*_*sto 52
event.composedPath()来自:https : //developer.mozilla.org/en-US/docs/Web/API/Event/composedPath
Event 接口的 compositionPath() 方法返回事件的路径,它是将调用侦听器的对象数组。
const target = document.querySelector('#myTarget')
document.addEventListener('click', (event) => {
const withinBoundaries = event.composedPath().includes(target)
if (withinBoundaries) {
target.innerText = 'Click happened inside element'
} else {
target.innerText = 'Click happened **OUTSIDE** element'
}
})Run Code Online (Sandbox Code Playgroud)
/* just to make it good looking. you don't need this */
#myTarget {
margin: 50px auto;
width: 500px;
height: 500px;
background: gray;
border: 10px solid black;
}Run Code Online (Sandbox Code Playgroud)
<div id="myTarget">
click me (or not!)
</div>Run Code Online (Sandbox Code Playgroud)
Ram*_*ami 40
经过研究,我找到了三种工作方案(我忘了页面链接供参考)
<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>
Run Code Online (Sandbox Code Playgroud)
<script>
$('body').on('click', function(e) {
if($(e.target).closest('#testDiv').length == 0) {
/* Hide dropdown here */
}
});
</script>
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)
小智 38
$("#menuscontainer").click(function() {
$(this).focus();
});
$("#menuscontainer").blur(function(){
$(this).hide();
});
Run Code Online (Sandbox Code Playgroud)
对我来说就好了.
小智 31
这完全适合我!
$('html').click(function (e) {
if (e.target.id == 'YOUR-DIV-ID') {
//do something
} else {
//do something
}
});
Run Code Online (Sandbox Code Playgroud)
34m*_*4m0 25
我不认为你真正需要的是当用户点击外面时关闭菜单; 您需要的是当用户点击页面上的任何位置时关闭菜单.如果您单击菜单,或关闭菜单,它应该关闭吗?
上面没有找到满意的答案促使我前几天写这篇博文.对于更迂腐的人来说,有许多值得注意的问题:
body { margin-left:auto; margin-right: auto; width:960px;}ben*_*enb 24
正如另一张海报所说,有很多陷阱,特别是如果您正在显示的元素(在这种情况下是一个菜单)具有交互元素.我发现以下方法相当健壮:
$('#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);
}
})
});
Run Code Online (Sandbox Code Playgroud)
Jit*_*mor 23
这种情况的简单解决方案是:
$(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();
}
});
Run Code Online (Sandbox Code Playgroud)
上面的脚本将隐藏divif divclick事件的外部是否被触发.
您可以在以下博客中查看更多信息:http://www.codecanal.com/detect-click-outside-div-using-javascript/
Ima*_*ghi 21
而不是使用可能有一些副作用的event.stopPropagation(),只需定义一个简单的标志变量并添加一个if条件.我测试了这个并正常工作,没有任何副作用的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";
}
});
Run Code Online (Sandbox Code Playgroud)
只需一个简单的if条件:
$(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
}
});
Run Code Online (Sandbox Code Playgroud)
Chr*_*ald 20
检查窗口单击事件目标(它应传播到窗口,只要它没有在其他任何地方捕获),并确保它不是任何菜单元素.如果不是,那么你就在菜单之外了.
或者检查点击的位置,看看它是否包含在菜单区域中.
Chu*_*eow 17
我有这样的成功:
var $menuscontainer = ...;
$('#trigger').click(function() {
$menuscontainer.show();
$('body').click(function(event) {
var $target = $(event.target);
if ($target.parents('#menuscontainer').length == 0) {
$menuscontainer.hide();
}
});
});
Run Code Online (Sandbox Code Playgroud)
逻辑是:当#menuscontainer显示时,将单击处理程序绑定到#menuscontainer仅在目标(单击)不是它的子项时隐藏的主体.
Tim*_*Tim 17
focusout辅助功能这里有一个答案(非常正确)说,关注click事件是一个可访问性问题,因为我们想迎合键盘用户。该focusout事件是在这里使用的正确内容,但它可以比其他答案中更简单地完成(并且在纯 JavaScript 中也是如此):
使用的“问题”focusout是,如果对话框/模式/菜单内的元素失去焦点,而焦点也位于“内部”,该事件仍然会被触发。event.relatedTarget我们可以通过查看(它告诉我们哪个元素将获得焦点)来检查情况是否并非如此。
dialog = document.getElementById("dialogElement")
dialog.addEventListener("focusout", function (event) {
if (
// We are still inside the dialog so don't close
dialog.contains(event.relatedTarget) ||
// We have switched to another tab so probably don't want to close
!document.hasFocus()
) {
return;
}
dialog.close(); // Or whatever logic you want to use to close
});
Run Code Online (Sandbox Code Playgroud)
上面有一个小问题,那就是relatedTarget可能是null。如果用户在对话框外部单击,这很好,但如果用户在对话框内部单击并且对话框碰巧不可聚焦,则这将是一个问题。要解决此问题,您必须确保进行设置,tabIndex=0以便您的对话框可聚焦。
Boh*_*ets 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();
}
});
Run Code Online (Sandbox Code Playgroud)
停止事件传播没有问题,并且更好地支持同一页面上的多个菜单,在第一个打开时单击第二个菜单将在stopPropagation解决方案中保留第一个菜单.
naz*_*yev 13
我在一些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);
Run Code Online (Sandbox Code Playgroud)
Dan*_*lip 13
该事件有一个名为event.path的属性,该属性是"树中所有祖先的静态有序列表".要检查事件是源自特定DOM元素还是其中一个子元素,只需检查该特定DOM元素的路径.它还可以用于通过逻辑OR检查some函数中的元素检查来检查多个元素.
$("body").click(function() {
target = document.getElementById("main");
flag = event.path.some(function(el, i, arr) {
return (el == target)
})
if (flag) {
console.log("Inside")
} else {
console.log("Outside")
}
});Run Code Online (Sandbox Code Playgroud)
#main {
display: inline-block;
}Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="main">
<ul>
<li>Test-Main</li>
<li>Test-Main</li>
<li>Test-Main</li>
<li>Test-Main</li>
<li>Test-Main</li>
</ul>
</div>
<div id="main2">
Outside Main
</div>Run Code Online (Sandbox Code Playgroud)
所以对于你的情况它应该是
$("body").click(function() {
target = $("#menuscontainer")[0];
flag = event.path.some(function(el, i, arr) {
return (el == target)
});
if (!flag) {
// Hide the menus
}
});
Run Code Online (Sandbox Code Playgroud)
小智 12
这是针对未来观众的vanilla JavaScript解决方案.
单击文档中的任何元素后,如果切换了单击元素的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);
})();
Run Code Online (Sandbox Code Playgroud)
(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);
})();Run Code Online (Sandbox Code Playgroud)
<a href="javascript:void(0)" id="toggle">Toggle Hidden Div</a>
<div id="hidden" style="display: none;">This content is normally hidden. click anywhere other than this content to make me disappear</div>Run Code Online (Sandbox Code Playgroud)
如果您要在同一页面上进行多次切换,可以使用以下内容:
hidden到可折叠项.(function () {
"use strict";
var hiddenItems = document.getElementsByClassName('hidden'), hidden;
document.addEventListener('click', function (e) {
for (var i = 0; hidden = hiddenItems[i]; i++) {
if (!hidden.contains(e.target) && hidden.style.display != 'none')
hidden.style.display = 'none';
}
if (e.target.getAttribute('data-toggle')) {
var toggle = document.querySelector(e.target.getAttribute('data-toggle'));
toggle.style.display = toggle.style.display == 'none' ? 'block' : 'none';
}
}, false);
})();Run Code Online (Sandbox Code Playgroud)
<a href="javascript:void(0)" data-toggle="#hidden1">Toggle Hidden Div</a>
<div class="hidden" id="hidden1" style="display: none;" data-hidden="true">This content is normally hidden</div>
<a href="javascript:void(0)" data-toggle="#hidden2">Toggle Hidden Div</a>
<div class="hidden" id="hidden2" style="display: none;" data-hidden="true">This content is normally hidden</div>
<a href="javascript:void(0)" data-toggle="#hidden3">Toggle Hidden Div</a>
<div class="hidden" id="hidden3" style="display: none;" data-hidden="true">This content is normally hidden</div>Run Code Online (Sandbox Code Playgroud)
Jov*_*i G 11
我很惊讶没有人真正认可的focusout事件:
var button = document.getElementById('button');
button.addEventListener('click', function(e){
e.target.style.backgroundColor = 'green';
});
button.addEventListener('focusout', function(e){
e.target.style.backgroundColor = '';
});Run Code Online (Sandbox Code Playgroud)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<button id="button">Click</button>
</body>
</html>Run Code Online (Sandbox Code Playgroud)
小智 8
如果你是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;}
Run Code Online (Sandbox Code Playgroud)
使用:
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();
});
Run Code Online (Sandbox Code Playgroud)
相反,使用流动中断,模糊/焦点事件或任何其他棘手的技术,只需将事件流与元素的亲缘关系匹配:
$(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)
}
});
Run Code Online (Sandbox Code Playgroud)
要删除单击外部事件侦听器,只需:
$(document).off("click.menu-outside");
Run Code Online (Sandbox Code Playgroud)
2020 使用原生 JS API最接近方法的解决方案。
document.addEventListener('click', ({ target }) => {
if (!target.closest('.el1, .el2, #el3')) {
alert('click outside')
}
})
Run Code Online (Sandbox Code Playgroud)
在文档上挂钩单击事件侦听器.在事件侦听器中,您可以查看事件对象,特别是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");
}
});
Run Code Online (Sandbox Code Playgroud)
小智 5
$(document).click(function() {
$(".overlay-window").hide();
});
$(".overlay-window").click(function() {
return false;
});
Run Code Online (Sandbox Code Playgroud)
如果单击文档,则隐藏给定元素,除非您单击该元素.
我在YUI 3中这样做了:
// Detect the click anywhere other than the overlay element to close it.
Y.one(document).on('click', function (e) {
if (e.target.ancestor('#overlay') === null && e.target.get('id') != 'show' && overlay.get('visible') == true) {
overlay.hide();
}
});
Run Code Online (Sandbox Code Playgroud)
我正在检查祖先是不是小部件元素容器,
如果目标不是打开小部件/元素,
如果我要关闭的小部件/元素已经打开(不那么重要).
小智 5
我们实施了一个解决方案,部分基于上述用户的评论,这对我们来说非常有效。当在这些元素之外单击时,我们使用它来隐藏搜索框/结果,不包括最初的元素。
// HIDE SEARCH BOX IF CLICKING OUTSIDE
$(document).click(function(event){
// IF NOT CLICKING THE SEARCH BOX OR ITS CONTENTS OR SEARCH ICON
if ($("#search-holder").is(":visible") && !$(event.target).is("#search-holder *, #search")) {
$("#search-holder").fadeOut('fast');
$("#search").removeClass('active');
}
});
Run Code Online (Sandbox Code Playgroud)
它首先检查搜索框是否已经可见,在我们的例子中,它还删除了隐藏/显示搜索按钮上的活动类。
Upvote为最受欢迎的答案,但添加
&& (e.target != $('html').get(0)) // ignore the scrollbar
Run Code Online (Sandbox Code Playgroud)
因此,单击滚动条不会[隐藏或不管]您的目标元素.
为了更容易使用,以及更具表现力的代码,我为此创建了一个jQuery插件:
$('div.my-element').clickOut(function(target) {
//do something here...
});
Run Code Online (Sandbox Code Playgroud)
注意: 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;
};
Run Code Online (Sandbox Code Playgroud)
默认情况下,click事件侦听器放置在文档上.但是,如果要限制事件侦听器作用域,则可以传入表示父级别元素的jQuery对象,该父级别元素将是将要侦听单击的顶级父级.这可以防止不必要的文档级事件侦听器.显然,除非提供的父元素是初始元素的父元素,否则它将不起作用.
使用如下:
$('div.my-element').clickOut($('div.my-parent'), function(target) {
//do something here...
});
Run Code Online (Sandbox Code Playgroud)
小智 5
如果有人好奇这里是javascript解决方案(es6):
window.addEventListener('mouseup', e => {
if (e.target != yourDiv && e.target.parentNode != yourDiv) {
yourDiv.classList.remove('show-menu');
//or yourDiv.style.display = 'none';
}
})
Run Code Online (Sandbox Code Playgroud)
和es5,以防万一:
window.addEventListener('mouseup', function (e) {
if (e.target != yourDiv && e.target.parentNode != yourDiv) {
yourDiv.classList.remove('show-menu');
//or yourDiv.style.display = 'none';
}
Run Code Online (Sandbox Code Playgroud)
});
这是纯JavaScript的简单解决方案。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;
})
Run Code Online (Sandbox Code Playgroud)
我已经使用下面的脚本并完成了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
}
})
Run Code Online (Sandbox Code Playgroud)
在下面找到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>
Run Code Online (Sandbox Code Playgroud)
您可以在这里阅读教程