Prevent right-click from opening context-menu, yet firing object's mouseClick event

Hi, I'm facing an unexpected issue : my goal is pretty basic, but i can't find any infos on how to achieve it.

This goal is : left-click on a DIV to fire a function with a "1" argument, right click on the same DIV to fire the same function with a "-1" argument.

I thought document.oncontextmenu = function(e) { e.preventDefault(); } only prevented the context-menu to appear, but it's also negating the right-click event : my function isn't launched.

The code for my div is :

`div.mouseClicked(function(e) {
myFunction(name, e.target.id);
e.preventDefault();
return false;
});`

function myFunction(name, id) { console.log( 'FUNCTION FIRED' ); if(mouseButton===LEFT) anotherfunction(1); if(mouseButton===RIGHT) anotherfunction(-1); }

My console.log didn't show, so i tried attaching the oncontextmenu to my div instead :

div.oncontextmenu = function(e) { myFunction(name, e.target.id); e.preventDefault(); return false; }

But this didn't work either. Since i'm not very familiar with how this event is handled, i came here seeking for help ! Thanks for reading this far, hope you can help :)

Answers

  • div.mouseClicked() might not so what you think is doing.

    First of all an to clarify, div is not the name of a variable but you are referring to a div element in your html code, right? Alright, in your html code you could do something like this

    <div id="my_div_has_a_name">
    </div>
    

    Then in your p5.js code you do this:

    var mydiv=select('#my_div_has_a_name');
    mydiv.mouseClicked(...);
    

    So what I am doing is grabbing the html item inside your p5.js sketch using the id assigned to the div element. Notice you might need to load the p5.dom.js after p5.js. Besides, I didn't test your click event code so I am not making suggestions on that part of the code for now. Give it a try and I hope this change will help you.

    Question: Maybe you want to assign this click function to all your divs elements? Is this is what you want to do, then you need another piece of code.

    Kf

  • Thanks for your answer ! Yeah, i'm pretty sure i don't fully understand the mouseClicked() function, which is the cause of my trouble !

    The thing is, the "div" in my "div.mouseClicked()" code is infact a p5 object, i selected it using "select('#'+id);" before assigning the mouseClicked event. Thus, everything is working fine when i left-click on my div !

    But it seems like a right-click doesn't trigger the function, since my log dosn't show in the console (eg. 'FUNCTION FIRED'). I thought the problem came from the context-menu overriding the event, but maybe the problem is elsewhere ?

    The original code is this :

    let d = select('#'+addToID); d.parent(map); d.style('left', percent.x+"%"); d.style('top', percent.y+"%"); // d.attribute('onclick', 'addRemIcon(name, this.id)'); d.mouseClicked(function(e) { console.log(e); addRemIcon(name, e.target.id); e.preventDefault(); return false; });

    (i even switched from the standard "onclick" to the p5 "mouseClicked()", thinking it would handle it differently.)

    My function code is :

    function addRemIcon(name, id) { console.log('FUNCTION FIRED'); if(mouseButton===LEFT) socket.emit('add remove map icon', { "name": name, "id": id, "val": 1 }); if(mouseButton===RIGHT) { socket.emit('add remove map icon', { "name": name, "id": id, "val": -1 }); console.log("RIGHT CLICKED"); } }

    Hope this can help ! And thanks again for such a fast (and really clear) answer !

  • Answer ✓

    Well, the solution was finally pretty obvious !

    Since "oncontextmenu" is triggered by a right click, i simply added an argument to my function, and :

    d.elt.oncontextmenu = function(e) {
          addRemIcon(name, this.id, "right");
          e.preventDefault();
          return false;
        }
    

    Now my function :

    function addRemIcon(name, id, button) { if(button==="left") socket.emit('add remove map icon', { "name": name, "id": id, "val": 1 }); if(button==="right") socket.emit('add remove map icon', { "name": name, "id": id, "val": -1 }); }

    Hope this could help someone some day ! (Thanks again kfrajer for taking on your time to care for my issue !)

  • edited April 2018

    Just a tip: No need to return false; if preventDefault() was invoked. :>
    Also, return false; works only for on() callbacks. L-)

  • edited April 2018

    Oh ok ! Thanks for the info, i don't really know the core difference between them, but i guess preventDefault() completely shuts the incomming event so no callback is given, thus not returning anything ?

    (By "on() callbacks", do you mean user interactive-event like onclick / onkeyup / onsubmit or so ?)

    (Plus, on my previous solution, a cleaner way to go would be to replace the "button" argument by "val")

    function addRemIcon(name, id, val) { socket.emit('add remove map icon', { "name": name, "id": id, "val": val }); }

  • edited April 2018

    (By "on() callbacks", do you mean user interactive-event like onclick / onkeyup / onsubmit or so ?)

    Correct! Only for those callbacks starting w/ "on":
    https://Developer.Mozilla.org/en-US/docs/Web/API/GlobalEventHandlers

    However, those callbacks registered w/ addEventListener() don't work w/ return false;:
    https://Developer.Mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener

    For both cases, invoking preventDefault() always work.

    ... but i guess preventDefault() completely shuts the incoming event...

    preventDefault() only cancels the default action for a given event:
    https://Developer.Mozilla.org/en-US/docs/Web/API/Event/preventDefault

    However, if you wish to disallow other registered callbacks, which haven't been invoked yet, to catch the same event, you need to call stopPropagation():
    https://Developer.Mozilla.org/en-US/docs/Web/API/Event/stopPropagation

Sign In or Register to comment.