开发者

How to get Javascript event to fire only when the background is clicked (and not other elements)?

开发者 https://www.devze.com 2022-12-09 23:03 出处:网络
I\'m trying to write a web app which replaces the context m开发者_StackOverflow社区enu (right-click menu) with my own customized ones.I want it so that when the user clicks on a table row, they get on

I'm trying to write a web app which replaces the context m开发者_StackOverflow社区enu (right-click menu) with my own customized ones. I want it so that when the user clicks on a table row, they get one certain context menu and when they click on the background of the page, they get a different one.

I have already written the menus and gotten them working. The problem comes in when trying to figure out how to get the background's menu to show ONLY when clicking on the background and how to get the table row's menu to show when that is clicked.

I tried using document.body.oncontextmenu for the body and and setting the oncontextmenu function for each table row, but the body's oncontextmenu function overrides the row's so I get the wrong menu. The menu for the table rows DOES work if I stop using the body's menu, so that's not the issue.

I could be using the wrong events, so is there a different event for just the background (and not the elements on top of the background)? Or a way to "prioritize" the events so the table row's function takes precedence?

This is how the code looks:

var tableMenu;
var bodyMenu;

window.onload = function()
{
    bodyMenu = new rightClickMenu("bodyMenu");
    document.body.oncontextmenu = function() { bodyMenu.show(); tableMenu.hide(); }
    bodyMenu.add("Add Entry", function()
    {
        alert("ADD");
    });
    
    tableMenu = new rightClickMenu("tableMenu", "tblSims");

    simRows = getElementsByClassName("trSimRow");
    for (var i in simRows)
        simRows[i].oncontextmenu = function() { tableMenu.show(this.id.substring(2)); bodyMenu.hide(); }

    tableMenu.add("Delete Entry", function(mac)
    {
        alert("DELETE");
    });
    
    document.body.onclick = function()
    {
        bodyMenu.hide();
        tableMenu.hide();
    };
}


You can capture the target element, e.g.:

$('*').click(function(e) {
    alert(e.target);
    alert(e.target.tagName);
    if(e.target.tagName == 'html') {
        // show background menu
    }
});


You have to work with the Javascript Event Propagation model. What happens is that your click event is automatically passed down the layers of objects on a page that have been registered as event listeners, unless you explicitly tell it to stop, try something like this:

function setupClickHandlers()
{
    document.getElementsByTagName('body')[0].onclick = doBodyMenu;
    document.getElementById('tableID').onclick = doTableMenu;
}

function doBodyMenu()
{
    //do whatever it does
}

function doTableMenu(e)
{
    //do whatever it does

    //stop the event propagating to the body element
    var evt = e ? e : window.event;

    if (evt.stopPropagation) {evt.stopPropagation();}
    else {evt.cancelBubble=true;}
    return false;
}

This should deal with the way each browser handles events.


$( document ).ready(function() {

    var childClicked = false;
    
    // myContainer is the nearest container div to the clickable elements 
    $("#myContainer").children().click(function(e) {
        console.log('in element');
        childClicked = true;
    });

    $("#myContainer").click(function(e){
        if(!childClicked) {
            console.log('in background');
            e.preventDefault();
            e.stopPropagation();
        }
        childClicked = false;
    });
});
#myContainer {
width:200px;
height:200px;
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="myContainer" style="">

<a href="#">link</a>

<div style="width:50px;height:50px;background-color: white;">
<a href="#">another link</a>
</div>

</div>

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号