Chrome for Android mis-measuring clientX/Y and the position for elementFromPoint
Reported by
richkore...@gmail.com,
May 23 2016
|
|||||
Issue descriptionChrome Version : 50.0.2661.89 URLs (if applicable) : https://jsfiddle.net/RichKorea/hs23a9sb/ Other browsers tested: Add OK or FAIL, along with the version, after other browsers where you have tested this issue: Chrome: Desktop - Okay - 50.0.2661.102 m Internet Browser on Android: Okay - not sure of the version Safari: Mobile - I tested an earlier version of my Fiddle and it worked as expected Safari: Desktop - Okay - 5.1.7 Firefox: Desktop - Okay - 46.0.1 IE: Desktop - Okay - 11.306 Edge: Desktop - Okay - 25 What steps will reproduce the problem? The Fiddle has instructions (1) (2) (3) What is the expected result? on touch events, clientX and Y should not equal pageX and Y, when scrolled - for Chrome on Android the values are the same. An additional complication is that elementFromPoint is working from the same wrong position. So long as I use the clientX as the position reference for elementFromPoint and use pageX for position, my page works, but as there are a couple of bug reports that talk about clientX (608394 and 605676) and if you fix just the clientX problem but not the elementFromPoint (which was an issue three years ago - 141840) then my page will break). All of the other browsers I tried reference clientX and elementFromPoint from the edge of the viewport. Only Chrome on Android is referencing from the edge of the document. What happens instead? Please provide any additional information below. Attach a screenshot if possible.
,
Jul 21 2016
input because this talks about touch events
,
Jul 21 2016
According to your instruction this only happens when you zoom and pan around. I believe this is a the intended effect of visual viewport whose zoom is transparent to the page. Assigning to bokan@ for further triage. If this happens when you scroll the page without zooming in then it is a bug.
,
Jul 21 2016
That's right, when you're zoomed in, the client coordinates are no longer relative to the visual viewport. They're not relative to the document either. They're relative to the "layout" viewport. You can see how it works here: bokan.ca/viewport/index.html Edge works the same way when zoomed in and this is intended behaviour so I'm marking as WontFix. Feel free to reply for more info.
,
Jul 23 2016
As the person who reported this bug, here’s some more details. Sorry the explanation is so long: I don’t know if it’s a touch issue or an Android vs Windows build issue. Chrome for Android (which of course uses touch) treats clientX differently than Chrome for Windows and Internet Browser for Android (the generic browser that came with my phone). I don’t have access to a Windows machine with a touch display, so I can’t say if the issue is related to touch events or to the Android build (compared to the Windows build). The bug’s not related to zoom – I was zooming my phone’s display when I first saw the different behavior for the code I was working on and zooming was the easiest way to be able to scroll the display horizontally. I modified my jsFiddle to have a 1000px width on the container so it could scroll horizontally. The results were the same, so the bug’s not related to zooming. bokan – you are correct that the client coordinates should be relative to the layout viewport, but my jsFiddle seems to show Chrome on Android is referencing the edge of the document. The browser that came pre-installed on my phone is referencing from the edge of the layout viewport, the same as Chrome on Windows. In the fiddle there are buttons that act as touch targets. When there’s a touch event, the fiddle uses the clientX/Y coordinates with elementFromPoint to get the element that was tapped. If it was one of the buttons, the fiddle will display the clientX value and which button. In the browser that came with Android, tapping the first button reports the X position as 127. Tapping the second button (without any scrolling) reports the X position as 321. Shifting the display towards the left so that the second button is in the original position of the first button and tapping the second button results in an X position of 111 (after sliding the display back to the right so I could read the value). This is the way it should work (client and elementFromPoint both work from the client values). When I run the fiddle in the Chrome browser on my phone, tapping the first button reports a similar X position of 100 and tapping the second button also has a similar value of 329 (compared to the values from the Android browser). When I shift the display to the left and tap the second button, the value comes through as 303. elementFromPoint does identifying that the second button was tapped. When I run the fiddle on Chrome on my laptop, I get the proper values (the values are referenced from the viewport, not the document edge). Since I don’t have access to a Windows machine with a touch display and Chrome installed, I can’t determine if it’s touch versus mouse that makes the difference or Android versus Windows that makes the difference. I’ve attached a collection of screen captures from the Android browser, Chrome on Android, and Chrome on Windows of the jsFiddle in operation that shows the difference value for Chrome on Android. I hope this makes the issue understandable.
,
Jul 26 2016
Hi RichKorea, I tried your fiddle and it seems to work correctly for me. I made the container 1000px wide and scrolled so that B3 was at the viewport left edge. Tapping it reports x values ~50. One thing to keep in mind, the jsfiddle is displayed inside an iframe. Stranger things happen when you display it in the root page (that seems to be what you're doing in your screen shot, could you share the link?). If you make the container 1000px, by default, Chrome on Android will actually expand the layout viewport to cover all the content horizontally (within limits). If that's occurring, there wont be any horizontal scrolling in the layout viewport, only on the visual, and that would explain the values you're seeing. To disable this behavior you can place a viewport meta tag that limits zooming: <meta name="viewport" content="minimum-scale=1, maximum-scale=1"> The layout viewport is sized to be the viewport at minimum-scale so using this meta tag will keep it from trying to encompass horizontal content. Give that a try and see if it works.
,
Aug 2 2016
Hi Bokan, Thanks for taking the time to look at my fiddle. My screenshots of the fiddle were taken from the fiddle draft page (I find JSFiddle’s draft page easier to use on a mobile device). If you were looking at the actual fiddle (the version with all of the HTML, CSS, and JavaScript) on an Android phone, JSFiddle’s use of iframes may cause different results (I didn’t try looking at the fiddle on my Galaxy phone as it would be too small). To make things simpler, I modified the fiddle code (which was based on the code from an earlier bug report) and put the code in a directory on my website at http://goo.gl/icNEDd. I tested the page from my site using a Samsung and an LG phone, running the page with both the browsers that came with the phones and Chrome. On both phones, the clientX and pageX values are the same on Chrome, but different on the Android browser after sliding (scrolling) the page to the left. The values are also different when I run the page on my laptop using Chrome, Firefox, Edge, IE11, Safari (old Windows version), and Opera. I installed Firefox on my phone and ran the page, which resulted in different client and page values after sliding the display. To see the problem, access the page with using an Android phone, first with the Internet browser that came with the phone, and then with the Chrome browser. Tapping the B1 & B2 buttons (without sliding the display to the left) will display the same values for clientX and pageX for both browsers. Sliding the displays to the left (so B2 is roughly in the same position as where B1 was), tapping the B2 button, and then sliding the display back to the original position (so you can see the results) should result in different client and page values being displayed for the Android browser and the same values for Chrome. Hopefully with this setup, you’ll be able to see how the Chrome mobile browser is returning different results. I have not tried the page on a Windows machine with a touch screen, so I can’t be sure if the problem is connected to Android or to touch. I’ve attached the HTML file I created for reference and in case the link to the page on my site doesn’t work. Regards, Rich
,
Aug 2 2016
Right, what you're seeing is what I mention in comment #4. When I load the link you give above, the page doesn't load at minimum scale. Try pinch-zooming out as far as possible. You'll note there's now no horizontal scrolling possible. This is the viewport that Chrome uses for client coordinates. Since there's no scrolling in this viewport, clientX will always match pageX. Zooming in in this model is kind of like taking a magnifying glass to a part of the page, it's mostly invisible to the page. I say mostly above because you'll notice window.scrollX does get reflected when pinch-zoomed. This is an unfortunate inconsistency that I'd like to fix shortly (see issue 489206 ). In any case, the fix here is easy: add `minimum-scale=1` to your viewport <meta> tag and it works as you expect.
,
Aug 3 2016
Hi Bokan, Thanks for pointing me to Issue 489206 . I hadn’t seen that before (the title isn’t related to clientX/Y). I’m all set. Rich
,
Sep 27 2016
|
|||||
►
Sign in to add a comment |
|||||
Comment 1 by tkonch...@chromium.org
, May 24 2016Labels: OS-Android