我有一些HTML菜单,当用户单击这些菜单的头部时,我会完全显示这些菜单。当用户在菜单区域外单击时,我希望隐藏这些元素。
jQuery是否可以实现这样的功能?
$("#menuscontainer").clickOutsideThisElement(function() {
// Hide the menus
});
我有一些HTML菜单,当用户单击这些菜单的头部时,我会完全显示这些菜单。当用户在菜单区域外单击时,我希望隐藏这些元素。
jQuery是否可以实现这样的功能?
$("#menuscontainer").clickOutsideThisElement(function() {
// Hide the menus
});
当前回答
如果您正在使用“弹出窗口”等工具,则可以使用“onFocusOut”事件。
window.onload=函数(){document.getElementById(“内部div”).focus();}函数loseFocus(){警报(“在外面单击”);}#集装箱{背景色:浅蓝色;宽度:200px;高度:200px;}#内部div{背景色:浅灰色;宽度:100px;高度:100px;}<div id=“container”><input type=“text”id=“inside div”onfocusout=“loseFocus()”></div>
其他回答
订阅捕获阶段的点击以处理调用preventDefault的点击元素。使用其他名称在文档元素上重新触发它,单击任意位置。
document.addEventListener('click', function (event) {
event = $.event.fix(event);
event.type = 'click-anywhere';
$document.trigger(event);
}, true);
然后,在需要单击外部功能的地方,订阅文档上的单击任意位置事件,并检查单击是否在您感兴趣的元素之外:
$(document).on('click-anywhere', function (event) {
if (!$(event.target).closest('#smth').length) {
// Do anything you need here
}
});
一些注意事项:
您必须使用文档,因为在发生单击的所有元素上触发事件是性能错误。这个功能可以封装到特殊的插件中,在外部点击时调用一些回调。您不能使用jQuery本身订阅捕获阶段。您不需要加载文档来订阅,因为订阅是在文档上进行的,甚至不在其主体上,所以它总是独立于脚本放置和加载状态而存在。
这里还有一个解决方案:
http://jsfiddle.net/zR76D/
用法:
<div onClick="$('#menu').toggle();$('#menu').clickOutside(function() { $(this).hide(); $(this).clickOutside('disable'); });">Open / Close Menu</div>
<div id="menu" style="display: none; border: 1px solid #000000; background: #660000;">I am a menu, whoa is me.</div>
插件:
(function($) {
var clickOutsideElements = [];
var clickListener = false;
$.fn.clickOutside = function(options, ignoreFirstClick) {
var that = this;
if (ignoreFirstClick == null) ignoreFirstClick = true;
if (options != "disable") {
for (var i in clickOutsideElements) {
if (clickOutsideElements[i].element[0] == $(this)[0]) return this;
}
clickOutsideElements.push({ element : this, clickDetected : ignoreFirstClick, fnc : (typeof(options) != "function") ? function() {} : options });
$(this).on("click.clickOutside", function(event) {
for (var i in clickOutsideElements) {
if (clickOutsideElements[i].element[0] == $(this)[0]) {
clickOutsideElements[i].clickDetected = true;
}
}
});
if (!clickListener) {
if (options != null && typeof(options) == "function") {
$('html').click(function() {
for (var i in clickOutsideElements) {
if (!clickOutsideElements[i].clickDetected) {
clickOutsideElements[i].fnc.call(that);
}
if (clickOutsideElements[i] != null) clickOutsideElements[i].clickDetected = false;
}
});
clickListener = true;
}
}
}
else {
$(this).off("click.clickoutside");
for (var i = 0; i < clickOutsideElements.length; ++i) {
if (clickOutsideElements[i].element[0] == $(this)[0]) {
clickOutsideElements.splice(i, 1);
}
}
}
return this;
}
})(jQuery);
可以为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')
}
这里的其他解决方案不适合我,所以我不得不使用:
if(!$(event.target).is('#foo'))
{
// hide menu
}
编辑:普通Javascript变体(2021-03-31)
我使用这个方法来处理在单击下拉菜单外部时关闭下拉菜单的问题。
首先,我为组件的所有元素创建了一个自定义类名。这个类名将被添加到组成菜单小部件的所有元素中。
const className = `dropdown-${Date.now()}-${Math.random() * 100}`;
我创建了一个函数来检查单击和单击元素的类名。如果clicked元素不包含我上面生成的自定义类名,它应该将show标志设置为false,菜单将关闭。
const onClickOutside = (e) => {
if (!e.target.className.includes(className)) {
show = false;
}
};
然后,我将单击处理程序附加到窗口对象。
// add when widget loads
window.addEventListener("click", onClickOutside);
……最后还有一些家政服务
// remove listener when destroying the widget
window.removeEventListener("click", onClickOutside);
我最后做了这样的事情:
$(document).on('click', 'body, #msg_count_results .close',function() {
$(document).find('#msg_count_results').remove();
});
$(document).on('click','#msg_count_results',function(e) {
e.preventDefault();
return false;
});
我在新容器中有一个关闭按钮,用于最终用户友好的UI。为了不通过,我不得不使用return false。当然,有一个A HREF带你去某个地方会很好,或者你可以调用一些ajax的东西。不管怎样,这对我来说都很好。这正是我想要的。