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

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

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

当前回答

尝试以下代码:

if ($(event.target).parents().index($('#searchFormEdit')) == -1 &&
    $(event.target).parents().index($('.DynarchCalendar-topCont')) == -1 &&
    (_x < os.left || _x > (os.left + 570) || _y < os.top || _y > (os.top + 155)) &&
    isShowEditForm) {

    setVisibleEditForm(false);
}

其他回答

我在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();
    }
});

我正在检查祖先是否不是小部件元素容器,如果目标不是打开控件/元素的对象,如果我想关闭的小部件/元素已经打开(不那么重要)。

当只有一个元素需要管理时,这里的解决方案工作得很好。然而,如果有多个元素,问题就复杂得多。e.stopPropagation()的技巧和其他所有技巧都不起作用。

我想出了一个解决方案,也许不是那么容易,但总比什么都没有好。看看:

$view.on("click", function(e) {

    if(model.isActivated()) return;

        var watchUnclick = function() {
            rootView.one("mouseleave", function() {
                $(document).one("click", function() {
                    model.deactivate();
                });
                rootView.one("mouseenter", function() {
                    watchUnclick();
                });
            });
        };
        watchUnclick();
        model.activate();
    });

尝试以下代码:

if ($(event.target).parents().index($('#searchFormEdit')) == -1 &&
    $(event.target).parents().index($('.DynarchCalendar-topCont')) == -1 &&
    (_x < os.left || _x > (os.left + 570) || _y < os.top || _y > (os.top + 155)) &&
    isShowEditForm) {

    setVisibleEditForm(false);
}

这里的其他解决方案不适合我,所以我不得不使用:

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);
 <div class="feedbackCont" onblur="hidefeedback();">
        <div class="feedbackb" onclick="showfeedback();" ></div>
        <div class="feedbackhide" tabindex="1"> </div>
 </div>

function hidefeedback(){
    $j(".feedbackhide").hide();
}

function showfeedback(){
    $j(".feedbackhide").show();
    $j(".feedbackCont").attr("tabindex",1).focus();
}

这是我想出的最简单的解决方案。