How can we ensure that pointer events return the same coordinates as touch events when the viewport is zoomed in?

I attempted to utilize pointer events (such as pointerdown) instead of using a combination of touch events (e.g. touchstart) and mouse events (e.g. mousedown) to determine the input event coordinates.

var bodyElement = document.body;

bodyElement.addEventListener("touchstart", function(e) {console.log("touch: " + e.changedTouches[0].clientX + " " + e.changedTouches[0].clientY);});
bodyElement.addEventListener("pointerdown", function(e) {console.log("point: " + e.clientX + " " + e.clientY);});

Everything works correctly until the viewport is zoomed in (e.g. android chrome zooming the webpage, device toolbar zoom factor other than 100% in chrome's dev tools...). At that point, the pointer events start reporting inaccurate values.

You can see the issue in the screenshots below:

1) Viewport scaled to 100%, click on a 300px*300px div at the bottom right corner:

2) Viewport scaled to 150%, click on a 300px*300px div at the bottom right corner:

Is there a solution for obtaining correct coordinates from pointer events?

Edit:
Added jsfiddle: jsfiddle

Answer №1

Instead of targeting the body, focus on reaching the specific div to avoid any changes in its orientation.

Consider trying out this approach:

const dostuffwithdiv = () =>{
  var u = document.getElementById('uniqueDiv');

  u.addEventListener("touchstart", e=> {
    var rect = e.target.getBoundingClientRect();
    var x = e.targetTouches[0].pageX - rect.left;
    var y = e.targetTouches[0].pageY - rect.top;
    var msg = `touch: ${x} ${y}`;
    console.log(msg);
  });
  u.addEventListener("pointerdown", e=> {
    var rect = e.target.getBoundingClientRect();
    var x = e.clientX - rect.left;
    var y = e.clientY - rect.top;
    var msg = `point: ${x} ${y}`;
    console.log(msg);
  });
}

document.onreadystatechange = dostuffwithdiv(); //due to jsfiddle environment
//you may want to handle this differently on a real frontend:
//document.addEventListener("DOMContentLoaded", dostuffwithdiv);

Although the fiddle below is set up differently at the bottom due to jsfiddle's internal workings, it still serves as a useful example. Feel free to ask if you need further clarification.

https://jsfiddle.net/L3tbsyax/42/

Answer №2

After spending some time experimenting, I realized that getting this to work was quite challenging due to recent changes in Chrome's behavior. Despite my limited knowledge, I managed to come up with a solution that closely mimics the functionality you were looking for:

In the HTML code below, I made sure to remove the border that was causing complications and could potentially add extra complexity later on.

<body style="margin:0; padding: 0;">
    <div id="uniqueDiv" style="width:300px;height:300px;background-color: black;"></div>
</body>

For the JavaScript part, here is what I came up with:

const handleDivEvents = () =>{
  var divElement = document.getElementById('uniqueDiv');

  divElement.addEventListener("touchstart", e=> {
    var rect = e.target.getBoundingClientRect();
    var x = e.targetTouches[0].clientX - rect.left;
    var y = e.targetTouches[0].clientY - rect.top;
    var msg = `Touch Event: ${x} ${y}`;
    console.log(msg);
  });
  divElement.addEventListener("mouseup", e=> {
    var msg = `Pointer Event: ${e.clientX} ${e.clientY}`;
    console.log(msg);
  });
}

// Run the function once the document has finished loading
document.onreadystatechange = handleDivEvents();

You can view the working example here.

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

Is there a way to immobilize an object in JavaScript without resorting to Object.freeze()?

Is there a way to freeze the following object without relying on Object.freeze()? Let's find out: const obj = { a:'test', b:'Something' } ...

Error: Missing 1 type argument(s) in generic type definition

I've developed an abstract class structure as shown below: export abstract class CsvFileReader<T> { data: T[] = [] constructor(public file: string) {} abstract mapRow(row: string[]): T read() { this.data = this.file .split(& ...

Could it be that the function is returning undefined because console.log is executing before the result is actually returned? Perhaps a promise

There is a function located in another file that I need to extract the response from and perform an action based on that response before completing my controller function. This is the snippet of code from the external file: exports.counter = function(com ...

Guide on dynamically displaying a page based on the response from express/mssql middleware

I have developed a full stack application that includes a registration feature which successfully adds data to the database. Now, I am looking for a way to conditionally display the home page based on whether the login credentials are correct. Within my l ...

Using multiple `setState` calls without synchronization can lead to issues, especially when one of them uses a value obtained from `

In my discovery: When there are two instances of setState The first one is invoked with a value obtained from await Both calls occur in the same thread It results in a scenario where one state is updated while the other remains unchanged. For instance: ...

Is it possible to single out the final element having a specific CSS class in the absence of a parent container?

I have the following elements dynamically rendered in an HTML file. <div class="vehicle"></div> <div class="vehicle"></div> My requirement is to add a style float:right inside CSS class vehicle for the second el ...

What are some strategies for dividing a webpage evenly between an image and a text-containing div?

I am currently working on emulating a layout that I came across on another website ( if you scroll down past the video and profiles). The layout involves splitting the page 50/50 with a picture that is responsive and maintains its size when the page is res ...

Troubleshooting Rails 4: Handling a 404 Not Found Error When Making an AJAX Call to a

After spending about an hour trying to figure this out, I am still stuck... The action in my oferts_controller.rb file looks like this: def update_categories @categories = Category.children_of(Category.find(params[:categories])) respond_to ...

Is your Ajax response suddenly failing to work after the initial attempt?

Describing my predicament: The code snippet below is what I have been using to insert a custom-designed div into my webpage. Initially, the div is successfully added; however, it stops working after the first instance. $('#addanother').click(fu ...

I'm confused as to why only one of my HTML pages is accepting my CSS styling - not sure what's going on

I am facing an issue where the CSS styles are only being applied to one of the HTML pages I created. Despite checking my code multiple times, everything seems to be correct. All the necessary files are saved on my laptop in the same folder for the website. ...

Is there a way to customize the color of a MUI styled component?

I have a customized MUI component that displays a circular badge in green. const StyledGreenBadge = styled(Badge)(({ theme }) => ({ '& .MuiBadge-badge': { backgroundColor: '#44b700', color: '#44b700', ...

What is the reason behind WP AJAX consistently returning a value of 0?

Having trouble retrieving a proper response, as it always returns 0. Here is the JavaScript code in the head section: q = new XMLHttpRequest(); q.open('POST', ajaxUrl); q.onreadystatechange = function () { if (q.readyState === 4) { ...

Ensuring the authenticity of user login credentials

I have a form in my HTML where the user needs to input their name and password. <html> <body> <form action="welcome.php" method="post"> Name: <input type="text" name="name"><br> Password: <input type="text" name="password ...

Get only the text content from a hyperlink using Tinymce-4

Within tinymce.activeEditor, I currently have this line of innerHTML code (part of a ul-list): <li><a href="#">Important words</a></li> When I place the caret within the sentence "Important words," and click a button with the foll ...

Creating a concise TypeScript declaration file for an established JavaScript library

I'm interested in utilizing the neat-csv library, however, I have encountered an issue with it not having a typescript definition file available. Various blogs suggest creating a basic definition file as a starting point: declare var neatCsv: any; M ...

Looking to showcase initial API data upon page load without requiring any user input?

Introduction Currently, I am retrieving data from the openweatherAPI, which is being displayed in both the console and on the page. Issue My problem lies in not being able to showcase the default data on the frontend immediately upon the page's fir ...

Modifying the value of a variable causes a ripple effect on the value of another variable that had been linked to it

After running the code below, I am receiving values from MongoDB in the 'docs' variable: collection.find({"Stories._id":ObjectID(storyId)}, {"Stories.$":1}, function (e, docs) { var results = docs; results[0].Stories = []; } I ...

How to programmatically clear an input field in Angular using Bootstrap's typeahead feature

My current setup involves utilizing a form to populate a list displayed alongside the form. The markup looks like: <form name="stateForm"> <input type="text" ng-model="model.name" typeahead="state for state in states | filter:$viewValue"> ...

What is the best way to toggle and slide two forms within a single page?

In this scenario, the goal is to display multiple forms on a single page, like a Login Form and Reset Password Form shown below. One form is initially hidden until a link is clicked, triggering an effect. The current setup includes a .toggle() effect that ...

The system has detected an invalid NSStringEncoding value of 0x8000100 while converting NSAttributedString to HTML

I encountered a warning in the debugger while using XCode: It detected an incorrect NSStringEncoding value of 0x8000100 when converting an NSAttributedString to html data. I am unsure of what is causing this issue or how to resolve it. Below is the code sn ...