Dan Dan - 2 months ago 11
Javascript Question

How can I fire an event when I right click on a div inside a canvas with jQuery

UPDATE: I have updated the code snippet to include the whole page as found in Firebug.

I have the following code:

<html><head>

<title>Welcome to CodeIgniter</title>

<!--[if IE]>
<script type="text/javascript" src="/assets/js/Jit/Extras/excanvas.js"></script>
<![endif]-->

<script src="/assets/js/jquery/jquery-1.4.2.min.js" type="text/javascript"></script>

<script src="/assets/js/Jit/jit.js" type="text/javascript"></script>
<script src="/assets/js/tree.js" type="text/javascript"></script>
<script src="/assets/js/jquery/jquery.rightClick.js" type="text/javascript"></script>


<script type="text/javascript">

$(document).ready(function() {
$(".node").rightClick(function() {
alert ("RIGHT CLICK");
});

$.getJSON("/ajax/fetch/tree", function(data) {
init(data);
});
});

$(".node").live("click", function() {
alert ($(this).attr("id"));
});


</script>

<style type="text/css">
html, body {
width:100%;
height:100%;
background-color:#444;
text-align:center;
overflow:hidden;
font-size:9px;
font-family:Verdana, Geneva, Arial, Helvetica, sans-serif;
margin:0;padding:0;
}
/* visualization style container */
#infovis {
background-color:#222;
position:relative;
width:900px;
height:500px;
}

a, a:link, a:visited {
color:#343439;
}
/* spacetree nodes CSS class */
.node {
background-color:transparent;
font-weight:bold;
overflow:hidden;
text-decoration:none;
position:absolute;
text-align:center;
padding:4px 1px 1px 1px;
}

.node:hover {
color:#393434;
}

.hidden{
display:none;
}
</style>
</head><body>

<div id="infovis">
<div id="mycanvas" style="width: 900px; height: 500px; position: relative;">
<canvas id="mycanvas-canvas" width="900" height="500" style="position: absolute; top: 0pt; left: 0pt; width: 900px; height: 500px;"></canvas>
<div id="mycanvas-label" style="overflow: visible; position: absolute; top: 0pt; left: 0pt; width: 900px; height: 0pt;">
<div id="1" class="node" style="position: absolute; width: 60px; height: 17px; cursor: pointer; color: rgb(51, 51, 51); font-size: 0.8em; text-align: center; padding-top: 3px; left: 200px; top: 265px;">0.0</div>
<div id="4" class="node" style="position: absolute; width: 60px; height: 17px; cursor: pointer; color: rgb(51, 51, 51); font-size: 0.8em; text-align: center; padding-top: 3px; left: 420px; top: 215px;">2.0</div>
<div id="5" class="node" style="position: absolute; width: 60px; height: 17px; cursor: pointer; color: rgb(51, 51, 51); font-size: 0.8em; text-align: center; padding-top: 3px; left: 420px; top: 240px;">2.1</div>
<div id="9" class="node" style="position: absolute; width: 60px; height: 17px; cursor: pointer; color: rgb(51, 51, 51); font-size: 0.8em; text-align: center; padding-top: 3px; left: 420px; top: 265px;">2.2</div>
<div id="10" class="node" style="position: absolute; width: 60px; height: 17px; cursor: pointer; color: rgb(51, 51, 51); font-size: 0.8em; text-align: center; padding-top: 3px; left: 420px; top: 290px;">2.3</div>
<div id="2" class="node" style="position: absolute; width: 60px; height: 17px; cursor: pointer; color: rgb(51, 51, 51); font-size: 0.8em; text-align: center; padding-top: 3px; left: 310px; top: 253px;">1.0</div>
<div id="6" class="node" style="position: absolute; width: 60px; height: 17px; cursor: pointer; color: rgb(51, 51, 51); font-size: 0.8em; text-align: center; padding-top: 3px; left: 640px; top: 275px; display: none;">3.0</div>
<div id="3" class="node" style="position: absolute; width: 60px; height: 17px; cursor: pointer; color: rgb(51, 51, 51); font-size: 0.8em; text-align: center; padding-top: 3px; left: 310px; top: 278px;">1.1</div>
<div id="8" class="node" style="position: absolute; width: 60px; height: 17px; cursor: pointer; color: rgb(51, 51, 51); font-size: 0.8em; text-align: center; padding-top: 3px; left: 530px; top: 228px;">5.0</div>
<div id="11" class="node" style="position: absolute; width: 60px; height: 17px; cursor: pointer; color: rgb(51, 51, 51); font-size: 0.8em; text-align: center; padding-top: 3px; left: 530px; top: 253px;">5.1</div>
</div>
</div>
</div>
<div class="node">HELLO WORLD!</div>
</body></html>


I want to be able to right click on one of the divs with the "node" class and then fire an event. Is there a way to do this with jQuery? I have looked at the context menu jQuery plugin found at http://www.javascripttoolbox.com/lib/contextmenu/. However, if I use $('node').contextMenu(...) it doesn't work. If I use $('infovis').contextMenu(...) the context menu works.

It looks like these divs are actually outside the canvas. I pulled this code straight from Firebug.

Answer

Try this:

$(document).ready(function(){ 
    $(document)[0].oncontextmenu = function() {return false;} 

    $("#infovis").delegate('.node','mousedown',function(e){ 
      if( e.button == 2 ) { 
         e.stopPropagation()
         alert('Right mouse button!'); 
         return false; 
       } else { 
         return true; 
        } 

    }); 
});

I assume #infovis is visible from the outset and you are using javascript to populate that div with .node divs. Thus, you want to use event delegation, so you are not binding to each node, but a parent node instead. This makes your code faster, even if you have 1000 .nodes. Also, you don't need to put the bindings in a callback.

We delegate to mousedown and capture the event if button == 2 (the right click button).

Also you disable default right click behavior by stopping the contextmenu event.

Let me know if that works for you.