jQuery 检查对象元素是否在另一个元素中

jQuery check if object element is inside another

我正在尝试创建一个简单的 jQuery 弹出菜单,但似乎无法找出用于检查某个元素是否在预定义元素中的脚本。

单击弹出触发器会启动 jQuery 函数。该函数保存以下变量: 单击的元素 (js_popup-trigger)、其主要父元素 (js_popup-container) 以及带有菜单项的实际菜单 (js_popup-menu)。

单击触发器后,菜单淡出 in/out,并向文档添加事件侦听器以检查用户是否在菜单外单击,在这种情况下应关闭,不应发生任何事情如果用户在其中单击,则转到菜单。

这是我无法弄清楚的部分 - 如何检测用户是在弹出元素内部还是外部单击?

我试过这个: if(!$(e.target).parent('.js_popup-container').length){

但是当你在页面上有多个弹出窗口时这并不适用,因为如果你点击其他任何地方,包括另一个弹出窗口,当前的弹出窗口应该关闭,但是如果你点击另一个具有相同的弹出窗口 [= js_popup-container 的 41=],那么它将保持打开状态,因为从技术上讲,它位于具有 class.

的元素内部
/*  Popup menu toggle
===========================================*/
$(document).on("click",".js_popup-trigger", function(e){
    e.preventDefault();


    //Set variables
    var element     = $(e.currentTarget),
        container   = element.parent('.js_popup-container'),
        menu        = element.next('.js_popup-menu');


    //Toggle the menu
    menu.fadeToggle(200);


    /*  Create a click listener for the document
    *   This is to close the menu if clicked outside of it */
    $(document).click(function closePopup(e){


        //If the clicked item is not in the popup, close it
        if(!$(e.target).parent(container).length){
            menu.fadeToggle(200);
            $(document).unbind('click',closePopup);
        }
    });
});

最后,我想实现的是一个只需要添加3个class就可以应用于任何弹出菜单的功能。 应该有在同一个页面上有多个弹出菜单的选项,当点击菜单外的任何地方时,它应该关闭。

当然,我愿意接受有关改进代码的建议,但此时我不想使用已有的插件。

编辑: 我知道已经有其他问题和解决方案与这个非常相似,但不同之处在于其他问题中给出的解决方案是检查被点击的目标是否在另一个具有特定 class name/id/selector.

我需要一些不同的东西,我已经将父元素(弹出容器)保存在一个变量中。我需要知道单击的元素是否在该已保存元素的内部。

使用已经找到的解决方案,我 运行 遇到了一个问题,因为我将在页面上有多个弹出窗口,所以如果我打开一个弹出窗口,然后单击另一个,第一个弹出窗口将保留打开而不是关闭,那是因为使用其他解决方案,我正在检查带有弹出窗口容器 class 的元素,它们都有,这意味着第一个弹出窗口不会关闭。

这取决于您希望方法的性能如何,但这里有一个简洁的选项,假设元素和容器都是 jQuery 对象。

if(element.parents().find(container).length == 1){
   // do work
}

我想出了一个目前适用于我当前应用程序的解决方案。

$(document).on("click",".js_popup-trigger", function(e){
    e.preventDefault();

    //Set variables
    var element     = $(e.currentTarget).closest('.js_popup-trigger'),
        container   = element.parent('.js_popup-container'),
        menu        = element.next('.js_popup-menu');

    //Toggle the menu
    menu.fadeToggle(200);

    //Add the open classes to the container and trigger
    container.toggleClass('js_popup-container--open');
    element.toggleClass('js_popup-trigger--open');

    /*  Create a click listener for the document
    *   This is to close the menu if clicked outside of it */
    $(document).click(function closePopup(e){

        //If the clicked item is not in the popup, close it
        if(!$(e.target).closest(container[0]).length && element.is(":visible")){

            //Close the popup
            menu.fadeOut(200);

            //Remove the added classes
            container.removeClass('js_popup-container--open');
            element.removeClass('js_popup-trigger--open');

            //Unbind the closePopup function from the document
            $(document).unbind('click',closePopup);
        }
    });
});

这样一来,您就可以在同一页面上添加任意数量的弹出窗口,并且它们都将独立于其他人工作 - 我发现的所有其他解决方案都使用通用 class 来检查是否弹出窗口是打开的,而不是实际的 element/object,这意味着如果您打开了另一个具有相同 class 的弹出窗口,那么单击新的弹出窗口将不会关闭第一个弹出窗口。这种方法解决了这个问题。

希望这对其他人有帮助,如果有人有更好的想法,我很乐意听取他们的意见!