jQuery.在两个相互叠加的元素上绑定上下文菜单事件

jQuery.bind context menu event on two elements overlaid on top of eachother

本文关键字:元素 绑定 上下文 事件 菜单 叠加 两个 jQuery      更新时间:2023-09-26

我有两个相互顶部的divs。我想要的是,当底部div被点击一个上下文菜单出现,当我点击上部div我想要一个不同的上下文菜单出现。divs需要保持在彼此的顶部。

我遇到的问题是,当我单击上部div时,绑定事件执行两次。我相信这是因为它们是相互叠加的,两个divs都有一个绑定事件附加到它们。

是否有一种方法,只有绑定事件执行一次单击div ?基本上优先考虑最上面的(Z轴)div

我有一个例子,你可以看到,当点击红色的div时,attributeMenu上下文菜单出现,但当你点击绿色的div时,attributeMenu and elementMenu上下文菜单出现。

下面是示例jsfiddle

部分代码:

addElementMenu();
addAttributeMenu();
// If the document is clicked somewhere
$(document).bind("mousedown", function (e) {
    // If the clicked element is not the menu
    if (!$(e.target).parents(".custom-menu").length > 0) {
        // Hide it
        $(".custom-menu").hide(100);
    }
});

// If the menu element is clicked
$(".custom-menu li").click(function () {
    // This is the triggered action name
    switch ($(this).attr("data-action")) {
        // A case for each action. Your actions here
        case "duplicate":
            duplicateItem(clicked);
            break;
        case "delete":
            deleteItem(clicked);
            break;
        case "copy":
            copyItem(clicked);
            break;
        case "cut":
            cutItem(clicked);
            break;
        case "paste":
            pasteItem();
            break;
    }
    // Hide it AFTER the action was triggered
    $(".custom-menu").hide(100);
});
function addElementMenu() {
    $('.element').bind("contextmenu", function (event) {
        // Avoid the real one
        event.preventDefault();
        //set clicked item
        clicked = $(this);
        parent = $(this).parent().attr('id');
        console.log(clicked);
        console.log(parent);
        // Show contextmenu
        $("#elementMenu").finish().show().css({
            top: event.pageY + "px",
            left: event.pageX + "px",
            display: 'block'
        });
    });
}
function addAttributeMenu() {
    $('.attribute').bind("contextmenu", function (event) {
        // Avoid the real one
        event.preventDefault();
        //set clicked item
        clicked = $(this);
        parent = $(this).parent().attr('id');
        console.log(clicked);
        console.log(parent);
        // Show contextmenu
        $("#attributeMenu").finish().show().css({
            top: event.pageY + "px",
            left: event.pageX + "px",
            display: 'block'
        });
    });
}
CSS:

.attribute {
    width: 400px;
    height: 200px;
    background-color: red;
}
.element {
    width: 200px;
    height: 100px;
    background-color: green;
}
.custom-menu {
    display: none;
    z-index: 1000;
    position: absolute;
    overflow: hidden;
    border: 1px solid #CCC;
    white-space: nowrap;
    font-family: sans-serif;
    background: #FFF;
    color: #333;
    border-radius: 5px;
    padding: 0;
}
.custom-menu li {
    padding: 8px 12px;
    cursor: pointer;
    list-style-type: none;
}
.custom-menu li:hover {
    background-color: #DEF;
}
HTML:

<div class='attribute' id="attributeID">
    <div class='element' id="elementID"></div>
</div>
<ul class='custom-menu' id="elementMenu">
    <li class='visibleElement' data-action="duplicate">Duplicate</li>
    <li class='visibleElement' data-action="delete">Delete</li>
    <li class='visibleElement' data-action="copy">Copy</li>
    <li class='visibleElement' data-action="cut">Cut</li>
    <li class='visibleAttribute' data-action="paste">Paste</li>
</ul>
<ul class='custom-menu' id='attributeMenu'>
    <li class='visibleAttribute' data-action="paste">Paste</li>
</ul>

使用stopPropagation(),这样当您右键单击子div时不会触发父div中的事件。

脚本:

function addElementMenu() {
    $('.element').bind("contextmenu", function (event) {
        // Avoid the real one
        event.preventDefault();
        // Avoid the event from bubbling up to parent
        event.stopPropagation();
        //set clicked item
        clicked = $(this);
        parent = $(this).parent().attr('id');
        console.log(clicked);
        console.log(parent);
        // Show contextmenu
        $("#elementMenu").finish().show().css({
            top: event.pageY + "px",
            left: event.pageX + "px",
            display: 'block'
        });
    });
}

小提琴