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 point of the horizontal scroll bar in WP Thesis?

There seems to be a horizontal scroll bar appearing at the bottom of my site, even though there is no content extending beyond the visible area. Can anyone provide guidance on how to fix this issue? My website is built on Wordpress 3.0 and utilizes the Th ...

Guide to setting up sub-routes in fastify

Currently, I am incorporating fastify as the web framework for my nodejs project. My aim is to organize and call all routes from a specific directory while having a base route established in the main JS file, similar to how it's done in express. Despi ...

Squashing the `require()` method in nwJS using emberJS

I am facing an issue with my nwjs application that connects to a web address hosting an ember application. I need to access the node context within the ember application to determine the user's operating system for updating purposes. I attempted to do ...

Handsontable: A guide on adding up row values

I have a dynamic number of columns fetched from the database, making it impossible to predict in advance. However, the number of rows remains constant. Here is an illustration: var data = [ ['', 'Tesla', 'Nissan', & ...

Guarantee: exclude all successful and unsuccessful responses and only carry out the .finally method

I have a function named request: function request (endpoint) { return axios.request(endpoint).then(api.onSuccess).catch(api.onError) } api.onSuccess: onSuccess (response) { let breakChain = false ... adding some logic here ... return break ...

Maximizing the number of divs arranged horizontally in HTML while utilizing the full line width

My website consists of several fixed-width div elements that are styled to flow inline using the display type inline-block. This layout creates empty space at the end of the line where subsequent div elements cannot be accommodated and have to wrap to the ...

A guide on incorporating multiple nested loops within a single table using Vue.js

Is it possible to loop through a multi-nested object collection while still displaying it in the same table? <table v-for="d in transaction.documents"> <tbody> <tr> <th>Document ID:</th> &l ...

Submitting forms with Ajax in IE(8)

Sample Google form Related spreadsheet I modified the original code to create two custom forms: First created form Second created form Both forms are functional on most browsers except for IE(8). Any idea why? First form: <!DOCTYPE html> <h ...

Update the website's navigation key for improved user experience

Can the navigation key on a website be altered from 'Tab' to another key, such as 'Enter', allowing for the focus to shift to the next element with the corresponding 'tabindex' when the 'Enter' key is pressed? ...

Exploring ways to create a dynamic background image that allows the rest of the page to float over seamlessly

Currently working on a responsive website and almost done with the build. However, I came across a site where an image appears to be floating behind the rest of the webpage content. Tried searching for a solution using w3.css without any luck. Any sugge ...

Decoding JSON data within a Flatlist component in React Native

As a newcomer to React Native, I am currently working on developing an Ecommerce application. For the backend, I am using Woocommerce (Wordpress) and trying to integrate the Woocommerce API response into my React Native App. However, I am facing an issue w ...

"Utilizing custom data tags for woocommerce to display the product selling price with wc_rbp

When developing a website on WooCommerce, I encountered the need to create 6 different price lists with fixed prices for each product, while also being able to apply a global discount percentage for the price list assigned to each customer. To handle the ...

Using Ant Design with Formik to dynamically set field values in a form

When I click the "Change" button in an Antd table with data, the entire line of data is passed to a function as an object. However, I am having trouble inserting the data into the fields. What should I do? How can I set data to Antd input using an externa ...

What's the most efficient way to iterate through this Array and display its contents in HTML?

I'm struggling to sort a simple array and I think the issue might be related to the time format. I'm not sure how to reference it or how I can properly sort the time in this array format for future sorting. //function defined to input values ...

Incorporating PruneCluster into an AngularJS Leaflet Directive for Enhanced Mapping

I am currently facing an issue with loading clustered markers for geojson data using PruneCluster. The clusters are not appearing on the map and there are no errors showing up in the console to assist with troubleshooting. Below is the snippet of my curr ...

Include a clickable hyperlink within a column in JQGrid that, when clicked, triggers a specific Jquery function

I am dealing with a JQgrid that only has 5 columns. Below is the code I have attempted: jQuery("#grdAnn6InvstDetails").jqGrid({ url: RootUrl + 'FDIAS/Ann6InvDtlsGridData', datatype: 'json', mtype: 'POST&ap ...

Progress to the following pages after each page remains inactive for 3 seconds

Is it possible for someone to assist me in creating a script that automatically switches between pages when the page is idle for 3 seconds? My current setup only allows for movement from one page to another, but I have 4 pages that I would like this featur ...

The registration page in PHP is malfunctioning, and the reason remains a mystery to me

Having trouble with my register page submit button. Any help is appreciated. Below is the structure of my SQL table: CREATE TABLE `USERS` ( `id` int(20) NOT NULL AUTO_INCREMENT PRIMARY KEY, `username` varchar(50) NOT NULL, `password` varchar(50) N ...

How can I position a Button at the center of my Grid item using Material UI?

In my React 16.13.0 application, I am utilizing Material UI's Grid and trying to center the content of a button in the middle of a row. Here is what I have tried: center: { alignItems: "center", width: "100%", }, halfRow: { width: "5 ...

Utilize a JSON object with ChartJS for data visualization

Recently, I've been working with a REST API that returns historical data in the following format: { "2021-6-12": 2, "2021-6-13": 3, "2021-6-14" :1 } This data represents the count of measurements taken on each date ...