anandaravindan
anandaravindan

Reputation: 2551

Prevent default context menu in kinetic JS stage rightclick?

I need to disable the context menu in kinetic js on click of stage. I have tried everything like event.preventDefault(), cancelbubble, event.stopPropagation() return false, but nothing works..

Here is an example in jsfiddle.. Wat change needs to be done to prevent default context menu from displaying

stage.on('click',stageClicked,true);
function stageClicked(event){
   if(event.button==2){
       event.cancelBubble = true;
       event.preventDefault();
           event.stopPropagation();

       return false;
   }
}

http://jsfiddle.net/xPbgf/

Upvotes: 3

Views: 2510

Answers (2)

projeqht
projeqht

Reputation: 3160

The above answer removes the context menu, but does not allow @user2045685 to select the event.targetNode on right click.

@user2045685 states in his comments that he found a workaround by using the getAllIntersection method, but I urge you not to use that alternative as that's not what it was intended for, the getAllIntersection method has very poor performance, and using event.targetNode works just fine.

getAllIntersections(pos)

get all shapes that intersect a point. Note: because this method must clear a temporarycanvas and redraw every shape inside the container, it should only be used for special sitations because it performs very poorly. Please use the Kinetic.Stage#getIntersection method if at all possiblebecause it performs much better

Source: Kinetic.Container#getAllIntersections

Instead, you can bind an event listener to your div#container and call event.preventDefault() to disable the context menu.

document.getElementById("container").addEventListener('contextmenu', function (event) {
  event.preventDefault();
});

You also need to add a "background rectangle" with the width and height of your stage, so that the layer can detect your clicks. That's why in @Brandon Boone's answer above he stated that the "on doesn't seem to do anything." for the stage. KineticJS expects a node to listen for events, so if you don't add a "transparent background", then stage.on("click") will only fire when you right click the green rectangle (but not the rest of the stage).

var bg = new Kinetic.Rect({
  width: stage.getWidth(),
  height: stage.getHeight()
});

// add bg first as your transparent background
layer.add(bg);
// add the shape to the layer
layer.add(rect);

Now you can use your stage.on('click', stgClicked) function with no problems and call event.targetNode inside your stgClicked function.

function stgClicked(event) {
  if (event.button == 2) {
     alert('rightclick');
     var node = event.targetNode;
     console.log(node);
  }
}

JSfiddle

Upvotes: 3

Brandon J. Boone
Brandon J. Boone

Reputation: 16472

Looks like you need to find the canvas reference within the stage object and attach the contextmenu event directly to it as passing it into on doesn't seem to do anything.

Try this:

Live Demo

var canvas = stage.content.childNodes[0]; 
if (canvas.addEventListener) {
    canvas.addEventListener('contextmenu', stgClicked, false); 
} else if (canvas.attachEvent)  {
    canvas.attachEvent('oncontextmenu', stgClicked);
}

If you want the targetNode, just check for it within the native javaScript event.

function stgClicked(event){
    var targetNode;
    if (event.srcElement)  targetNode = event.srcElement;
    else if (event.target) targetNode = event.target;

    alert(targetNode.nodeName);
}

Upvotes: 2

Related Questions