我有一些HTML菜单,当用户单击这些菜单的头部时,我会完全显示这些菜单。当用户在菜单区域外单击时,我希望隐藏这些元素。
jQuery是否可以实现这样的功能?
$("#menuscontainer").clickOutsideThisElement(function() {
// Hide the menus
});
我有一些HTML菜单,当用户单击这些菜单的头部时,我会完全显示这些菜单。当用户在菜单区域外单击时,我希望隐藏这些元素。
jQuery是否可以实现这样的功能?
$("#menuscontainer").clickOutsideThisElement(function() {
// Hide the menus
});
当前回答
标记为接受答案的答案没有考虑到元素上可以有覆盖,如对话框、弹出窗口、日期选择器等。单击这些按钮不应隐藏元素。
我制作了自己的版本,确实考虑到了这一点。它是作为KnockoutJS绑定创建的,但它可以很容易地仅转换为jQuery。
它通过第一次查询所有具有z索引或绝对位置的可见元素来工作。然后,如果在外部单击,它会根据我想要隐藏的元素来测试这些元素。如果是命中,我会计算一个新的边界矩形,该矩形考虑到覆盖边界。
ko.bindingHandlers.clickedIn = (function () {
function getBounds(element) {
var pos = element.offset();
return {
x: pos.left,
x2: pos.left + element.outerWidth(),
y: pos.top,
y2: pos.top + element.outerHeight()
};
}
function hitTest(o, l) {
function getOffset(o) {
for (var r = { l: o.offsetLeft, t: o.offsetTop, r: o.offsetWidth, b: o.offsetHeight };
o = o.offsetParent; r.l += o.offsetLeft, r.t += o.offsetTop);
return r.r += r.l, r.b += r.t, r;
}
for (var b, s, r = [], a = getOffset(o), j = isNaN(l.length), i = (j ? l = [l] : l).length; i;
b = getOffset(l[--i]), (a.l == b.l || (a.l > b.l ? a.l <= b.r : b.l <= a.r))
&& (a.t == b.t || (a.t > b.t ? a.t <= b.b : b.t <= a.b)) && (r[r.length] = l[i]));
return j ? !!r.length : r;
}
return {
init: function (element, valueAccessor) {
var target = valueAccessor();
$(document).click(function (e) {
if (element._clickedInElementShowing === false && target()) {
var $element = $(element);
var bounds = getBounds($element);
var possibleOverlays = $("[style*=z-index],[style*=absolute]").not(":hidden");
$.each(possibleOverlays, function () {
if (hitTest(element, this)) {
var b = getBounds($(this));
bounds.x = Math.min(bounds.x, b.x);
bounds.x2 = Math.max(bounds.x2, b.x2);
bounds.y = Math.min(bounds.y, b.y);
bounds.y2 = Math.max(bounds.y2, b.y2);
}
});
if (e.clientX < bounds.x || e.clientX > bounds.x2 ||
e.clientY < bounds.y || e.clientY > bounds.y2) {
target(false);
}
}
element._clickedInElementShowing = false;
});
$(element).click(function (e) {
e.stopPropagation();
});
},
update: function (element, valueAccessor) {
var showing = ko.utils.unwrapObservable(valueAccessor());
if (showing) {
element._clickedInElementShowing = true;
}
}
};
})();
其他回答
老实说,我不喜欢以前的任何解决方案。
要做到这一点,最好的方法是将“点击”事件绑定到文档,并比较该点击是否真的在元素之外(就像Art在建议中所说的那样)。
然而,您会遇到一些问题:您永远无法解除绑定,并且无法使用外部按钮打开/关闭该元素。
这就是为什么我编写了这个小插件(点击此处链接),以简化这些任务。能简单一点吗?
<a id='theButton' href="#">Toggle the menu</a><br/>
<div id='theMenu'>
I should be toggled when the above menu is clicked,
and hidden when user clicks outside.
</div>
<script>
$('#theButton').click(function(){
$('#theMenu').slideDown();
});
$("#theMenu").dClickOutside({ ignoreList: $("#theButton") }, function(clickedObj){
$(this).slideUp();
});
</script>
如果您只想在单击按钮时显示一个窗口,而在单击外部时取消显示该窗口。(或再次按下按钮)此波纹管工作良好
document.body.onclick = function() { undisp_menu(); };
var menu_on = 0;
function menu_trigger(event){
if (menu_on == 0)
{
// otherwise u will call the undisp on body when
// click on the button
event.stopPropagation();
disp_menu();
}
else{
undisp_menu();
}
}
function disp_menu(){
menu_on = 1;
var e = document.getElementsByClassName("menu")[0];
e.className = "menu on";
}
function undisp_menu(){
menu_on = 0;
var e = document.getElementsByClassName("menu")[0];
e.className = "menu";
}
别忘了这个按钮
<div class="button" onclick="menu_trigger(event)">
<div class="menu">
以及css:
.menu{
display: none;
}
.on {
display: inline-block;
}
可以为DOM元素设置tabindex。当用户在DOM元素外部单击时,这将触发一个模糊事件。
Demo
<div tabindex="1">
Focus me
</div>
document.querySelector("div").onblur = function(){
console.log('clicked outside')
}
document.querySelector("div").onfocus = function(){
console.log('clicked inside')
}
使用not():
$("#id").not().click(function() {
alert('Clicked other that #id');
});
单击元素时,这将切换导航菜单。
$(document).on('click',函数(e){var elem=$(e.target).最近('#menu'),box=$(e.target).最近('#nav');if(元素长度){e.预防违约();$('#nav').tggle();}否则如果(!box.length){$('#nav').hide();}});<script src=“https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js“></script><li id=“menu”><a></a></li><ul id=“nav”><!--单击菜单时,导航将切换(在本例中它可以是一个图标)--><li class=“page”><a>第1页</a></li><li class=“page”><a>第2页</a></li><li class=“page”><a>第3页</a></li><li class=“page”><a>第4页</a></li></ul>