Guide on implementing event listener for right click using pure JavaScript (VANILLA JS)

I need the div to appear wherever the cursor is holding down the right mouse button.

In my scenario, I am using the following code:

<div class="d-none" id="item"></div>
#item{
  position: absolute;
  top: 0;
  left: 0;
  width: 100px;
  height: 100px;
  background: royalblue;
}
.d-none{
  display: none;
}
var myMouseX, myMouseY;

function getXYPosition(e) {
    myMouseX = (e || event).clientX;
    myMouseY = (e || event).clientY;
    
    getPosition(myMouseX, myMouseY);
    
    
    function getPosition(x, y) {
        console.log('X = ' + x + '; Y = ' + y);
      let div = document.querySelector("#item");
      if (div.classList.contains('d-none')) {
        div.classList.remove('d-none');
      } else {
        div.classList.add('d-none');
      }
      divX = x + "px";
      divY = y + "px";
      div.style.transform = `translate(calc(`+divX+` - 50%) , calc(`+divY+` - 50%))`;
    }
}

window.addEventListener('contextmenu', function (e) {
  e.preventDefault();
  var pressTimer;
  
  pressTimer = setTimeout(function() {
    getXYPosition(e);
  }, 1000);

  window.addEventListener('mouseup', function (){
    clearTimeout(pressTimer);
  });
});

You can also view my Fiddle

It currently works with a left click by default using window.addEventListener('click')

So now, how do I change it to activate when holding the right click for a few seconds?

Answer №1

Utilizing the MouseEvent API and its events like mousedown and mouseup, we can analyze the event.button property to determine which mouse button the user is using. By monitoring the time duration between mousedown and mouseup, we can make decisions on actions to take when the mouse button is released, such as executing a custom function like showOrHideDiv.

The contextmenu event is triggered after a right-click (unless the context menu is already visible). It is possible to override the default behavior of the context menu if needed; however, this should be done cautiously and sparingly.

It's important to note that the approach used here assumes that users will not access the context menu using their keyboards, potentially leading to accessibility challenges and unforeseen issues for users. Hence, it's advisable to avoid intercepting the default right-click behavior whenever feasible, opting instead for alternatives like Shift + right-click unless users consciously choose to switch to the new behavior.

// Constants definition and main (`mousedown`) listener addition
const
  div = document.querySelector("#item"),
  RIGHT = 2,
  DELAY = 150;
document.addEventListener('mousedown', forceDelay);

// Main listener sets subsequent listeners
function forceDelay(event){

  // Proceed only if the right mouse button is pressed
  if(event.button != RIGHT){ return; }

  // Enable contextmenu and disable custom response
  document.removeEventListener('contextmenu', suppressContextMenu);
  document.removeEventListener('mouseup', showOrHideDiv);

  // After 150ms, disable contextmenu and enable custom response
  setTimeout(
    function(){
      document.addEventListener('contextmenu', suppressContextMenu);
      document.addEventListener('mouseup', showOrHideDiv);
    },
    DELAY
  );
}

// The `contextmenu` event listener
function suppressContextMenu(event){
  event.preventDefault();
}

// The `mouseup` event listener
function showOrHideDiv(event){
  if(event.button != RIGHT){ return; }
  const
    x = event.clientX,
    y = event.clientY;
  div.classList.toggle('d-none'); // classList API includes `toggle`
  div.style.transform = `translate(calc(${x}px - 50%), calc(${y}px - 50%)`;
}
#item{ position: absolute; top: 0; left: 0; width: 100px; height: 100px; background: royalblue; }
.d-none{ display: none; }
<div id="item" class="d-none"></div>

EDIT
Note: While this script functions correctly in a standalone HTML file using Chrome, there may be unexpected behavior when run within a Stack Overflow snippet, especially with touchpad devices. If you encounter similar issues, consider pasting the code into a <script> element in an HTML file (with CSS in a <style> element) to observe proper functionality.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the reason behind the automatic activation of a function when a nested React modal is

I've been experimenting with using react-responsive-modal and then switching to react-modal, but I'm encountering the same issue. Additionally, all my forms are built using react-hook-form. The problem arises when I have one modal triggering ano ...

Having trouble getting Vue-Select2 to display properly in Vuejs?

After setting up the vue3-select2-component and following their instructions, I encountered an issue where the component was not displaying in the output on the html page, even though the code for it was present in the source code. For context, I am using ...

Replicate the functionality of a mouse scrolling event

I have incorporated Jack Moore's Wheelzoom jQuery plugin to zoom and drag an SVG image on my website. However, I also want to include manual zoom in and out buttons for the users. I am considering two options to achieve this - triggering a mouse whe ...

What action is triggered on an Apple iPhone when a notification is tapped?

Currently, I am working on a React application and testing it on an Apple mobile phone. One issue I encountered is that when I receive an SMS, the number appears as a suggestion above the keyboard. I want to be able to tap on this number and have it automa ...

"Enhance Your Website with qTip2 Feature to Load Multiple AJAX Sites Simult

I'm currently utilizing the qTip2 library for my project and I've implemented their AJAX retrieval functions following this example: http://jsfiddle.net/L6yq3/1861/. To enhance my query, I have modified their HTML to include multiple links. The ...

Leverage the power of TypeScript by enabling the noImplicitAny flag when working

Currently, I am looking to activate the noImplicitAny flag in my compiler. My main issue lies with utilizing lodash/fp as there are no typings available at this moment. Due to this, the compiler is generating errors due to the absence of a definition file ...

When comparing two state arrays in React, it is important to note that they will not be considered equal and return a boolean (True

As I attempt to compare two arrays stored in my state, my goal is to set a boolean variable to "true" if they match. However, my current if statement fails to detect equality between the arrays. I'm performing this comparison within a setInterval() f ...

"NODEJS: Exploring the Concept of Key-Value Pairs in Object

I am facing a challenge with accessing nested key/value pairs in an object received through a webhook. The object in req.body looks like this: {"appId":"7HPEPVBTZGDCP","merchants":{"6RDH804A896K1":[{"objectId&qu ...

Forgetting your password with React JS

On my login page, there is a button labeled "Forget my password". When I click on this button, I want to be taken directly to the correct page for resetting my password. Currently, when I click on "forget my password", it displays beneath the login sectio ...

Display Numerous Values Using Ajax

Having difficulty showing data from the 'deskripsisrt' table in a modal bootstrap? I have successfully displayed from the 'srtptr' table, but not sure how to proceed with the 'deskripsisrt' table. Here's a snippet from my ...

Setting up authorization levels for roles in Discord.js

Hi everyone, I came across this script that deals with users posting invite links. How can I whitelist specific channels to prevent the bot from banning or kicking users for posting invite links? Any help would be greatly appreciated. Thank you. adminCli ...

Tips for accessing the 'index' variable in *ngFor directive and making modifications (restriction on deleting only one item at a time from a list)

Here is the code snippet I'm working with: HTML: <ion-item-sliding *ngFor="let object of objectList; let idx = index"> <ion-item> <ion-input type="text" text-left [(ngModel)]="objectList[idx].name" placeholder="Nam ...

Creating customized JQuery UI tabs to perfectly accommodate the available horizontal space

Can JQuery UI Tabs be modified to fill the horizontal space and stack to the left? In order to achieve this, could we consider using a markup like the one below: <table width="100%"> <tr> <td> ...content... </td> ...

Angular JS form cloning feature

I'm facing a challenge in creating a dynamic form with multiple sections. At the end of the form, I want to include a "Add New Form" button which will duplicate the existing form below it, each with its own save button. What's the most effective ...

issue encountered during resource provider setup

Below is my code snippet where I'm attempting to populate a table using ngResource in a RESTful manner. However, when I include configuration directives, I encounter an uncaught object MINERR ASST:22 error. var app = angular.module('infra&apo ...

Trick for using :checked in CSS

Is it possible to change the color of a deep linking div using an input checkbox hack in the code below? <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /&g ...

Signing in using Passport.js with mongoDB authentication

Apologies if this question appears redundant, but I am struggling to resolve an issue with a "MISSING CREDENTIALS" error when trying to implement user login using email and password. Despite going through numerous responses, none have provided a solution. ...

Issues within jQuery internal workings, implementing improved exception handling for fn.bind/fn.apply on draggable elements

I've been experimenting with wrapping JavaScript try/catch blocks as demonstrated on this link. It functions properly, essentially encapsulating code in a try/catch block to handle errors like so: $.handleErrors(function(e){ console.log("an erro ...

Tips for turning off hash-based redirection in AngularJS

Here is a specific URL: http://www.something.com/sometest/test/#registration Some code has been written based on #registration for Internet Explorer. However, when using AngularJS, it redirects to the following URL, which disrupts the logic: http://www ...

console fails to return a function even when it is defined

After clicking the "stopCrash" button, I want the function backAgain to be executed 2 seconds later. However, I am encountering an error in the console: Uncaught TypeError: this.backAgain is not a function. Do you have any suggestions on how to fix this i ...