1

Using a div, I created a menu that must appear when the user right-clicks the first row of a table:

HTML

<table>
  <tr onMouseDown='showMenu(event)' onContextMenu='return false'>
    <td>First row</td>
  </tr>
  <tr>
    <td>Second row</td>
  </tr>
</table>
<div id='divMnuTable' style='display:none' class='mnuTable'>Menu</div>

Javascript

function showMenu(e) {
    e = e || window.event;
    // get mouse coordinates
    var docEl = document.documentElement;
    var scrollLeft = docEl.scrollLeft || document.body.scrollLeft;
    var scrollTop  = docEl.scrollTop || document.body.scrollTop;
    var x = e.pageX || (e.clientX  + scrollLeft);
    var y = e.pageY || (e.clientY  + scrollTop);
    // show the menu
    var div = document.getElementById('divMnuTable');
    div.style.left = x+'px';
    div.style.top = y+'px';
    div.style.display = 'block';
}

CSS

table {
  border: 1px solid black;
}
tr:nth-child(odd) {
  background-color: #CCFFCC;
}
.mnuTable {
    background-color: #90A090;
    position:absolute;
}

JSFiddle: https://jsfiddle.net/q5brjfyw/

I can't reproduce the error in the fiddle above, but it happens on my Firefox/Ubuntu. (In the fiddle, the console says "showMenu is not defined" -- is this usual behavior for javascript in jsfiddle.net? Because the function is there on the Javascript panel!).

What is happening is: without this line

    div.style.display = 'block';

Firefox's context menu don't show up. That's what I want, and I get it because of the onContextMenu='return false'. But when I add

    div.style.display = 'block';

it shows both, my div-menu and Firefox context menu! Why is that? I've tried other commands to hide the context menu, but it keeps showing. I tried all of the below, isolated and mixed:

e.preventDefault();
if (event.stopPropagation)
    event.stopPropagation();
event.cancelBubble = true;
return false;

So, how do I hide the default context menu to show my own menu instead?

Rodrigo
  • 4,706
  • 6
  • 51
  • 94
  • FYI, about the showMenu issue... http://stackoverflow.com/a/16160752/2647442 – Marie Dec 21 '15 at 14:39
  • Any other errors in the `console`? – Mosh Feu Dec 21 '15 at 14:40
  • @MoshFeu in my program no errors at all. In jsfiddle, lots of blue exclamation points on loading, but only this reference error when I click the table. – Rodrigo Dec 21 '15 at 14:47
  • @Rodrigo If I had to guess, and it is only a guess... I think that the reason this isnt working is that you are successfully canceling the context menu for your child element but the parent is still firing its first. You could block it for the document if you really want to get it working easily. `document.oncontextmenu = function (e) {e.preventDefault();return false;}` – Marie Dec 21 '15 at 14:48
  • @ToniW, why can't I see the Frameworks & Extensions panel in jsfiddle? For your guess, I need the default menu in other parts of the screen, so I think this is not going to work. – Rodrigo Dec 21 '15 at 14:50
  • 1
    It is under the gear in the top right of the Javascript window. – Marie Dec 21 '15 at 14:52

1 Answers1

3

You are displaying the menu in a onmousedown handler and hiding the native menu in a oncontextmenu handler. The spec doesn't say whether one should run before the other.

What happens is that in Firefox, the onmousedown handler runs first, so your custom menu shows up, and then the oncontextmenu runs on your custom menu that appeared. There is no return false in that element, so the native menu shows up.

You need to trigger your custom menu inside the oncontextmenu handler:

<tr oncontextmenu="showMenu(event); return false;">

PS: export the showMenu function in the JS tab so that it can be used outside of that tab (window.showMenu = showMenu).

matteodelabre
  • 443
  • 5
  • 13