This issue is particularly difficult to explain...
In Mobile Safari (and not in Chrome on Android), when an input is focused and the view adjusts to put the input in the center of the screen, I've noticed that sometimes the elements that were previously there still have their touch events in place.
See the video below, in which I click slightly above the "apply" button, which ends up clicking on the "total price" header, which causes the dropdown to collapse. Obviously, that ghost touch event should not be there.
Basically, when I focus on the input, the screen moves as expected, but the touch events for the elements that were there before don;t move with them. If I touch in the same place that an element used to be, it triggers that event.
https://youtu.be/5tFNfnd5RO4
I know for sure that the event being triggered here is the one for the "total price" bar, because if I click slightly below it to the right, I can trigger the event for the "change" button.
Note that this doesn't happen consistently. I cannot replicate this 100% of the time, but I was able to capture it on video.
This is a known bug in iOS and they say they're going to fix it in the 11.3 release.
https://www.apple.com/newsroom/2018/01/apple-previews-ios-11-3/
Related
I'm working on an a webapp, where I need to adapt the contents of the screen when the virtual keyboard is expanded. Luckily, someone has already created an example of this here:
https://pmusaraj.github.io/ios15-bottom-bar2.html
When tapping on the text area, it correctly resizes. However, there is a small delay between the tap and when the resize happens in iOS 15.5. This is because the resize event doesn't seem to fire fully until after the keyboard is expanded. In iOS Chrome, interestingly, this does not happen and it works correctly.
Are there any workarounds to get Safari to fire the event sooner? Or alternative approaches to achieving a similar effect?
As of today there are no real solutions for this.
The only "workaround" that I found is to detect when the keyboard opens and closes with regular events like focus and blur. But you can't guess the final visualViewport sizes because there are different keyboards so this wasn't an option for me.
My "solution" to this issue was extend the modal and its background fade beyond the viewport with after elements (see here). That way there is still a jump between opening and closing the keyboard, but at least the look is a bit more consistent.
So, there's an html page with an image map (img tag with usemap attribute) and clickable areas. Lately, I think after iOS 15 upgrade on iphone (XR, XS, 13), Safari stops firing onclick event on areas. Initially onclick works if you tap lightly, with quick finger presses, but as soon as you tap a little longer (just a bit stronger tap, or a long press) it starts behaving as if there's no map and areas associated with the image.
You can test here https://demo.rezmagic.com/maptest.html
If you see "area click" messages, it works correctly. When you start seeing "image click" messages, it means it's broken - it does not detect areas anymore. If you reload page, it starts to work correctly again.
Any ideas on what's going on here? Possible workaround? I submitted a Safari bug on Apple feedback but I am not sure it was the right place.
meeks seems to be correct about the OCR capability of newer Safari browsers breaking image maps.
The following is one workaround that you can use, but it will break the OCR capability:
Create a transparent gif of the same size as the imagemap. Let's call it placeholder.gif. Then add it in-front of the actual image and put an image map on that, like so:
<img src="placeholder.gif" style="position: absolute; z-index: 10;" usemap="#Map" />original image here
It works for me.
This is absolutely a Safari bug on mobile and desktop and it's been driving me nuts. Your image doesn't replicate the issue on desktop safari, but those with higher resolution and more obvious text do.
What's happening is that Safari now OCRs images to allow users to select and copy text from them. It does this by adding shadow DOM elements containing the text that float above the image, all contained within one DIV that entirely covers the image. This doesn't happen instantly, but seems to take a little time and perhaps depend on user interaction with the image.
You can watch this happen by opening the MDN web docs page for the map element here and looking at the Example (not the demo) with Inspect Element. The img tag with the map starts out simple, but once it shows that it has children you can expand it and see the shadow DOM elements. Once those are added the map no longer functions, presumably because the overlay elements pass through clicks to the image but not the map.
I had developed a workaround where you listen for click events on the image, get the click event's offsetX and offsetY coordinates, then iterate through the elements to compare the event's offsets with the coordinates, and then trigger a click on the that matches.
However, then I realized that iOS 15.4 came out today and so I upgraded my iPhone and it seems to be fixed now without any workarounds. So just upgrade and you should be fine.
The question
When window.onresize event is fired, the bottom menu should become hidden if window.innerHeight is smaller than it was at window.onload.
Will this behave consistently across mobile browsers and operational systems?
Rationale
This is the solution I found to deal with the fact that mobile keyboards resize the viewport when they come out. If the bottom menu is not hidden when the keyboard comes into view, it will get stacked upon the keyboard.
This solution works as expected on Chrome v80 running on Android 7.1.
I wonder, however, if the below cases are common, since they would brake the mechanism:
Browsers that won't trigger the resize event when the keyboard comes in and/or leaves
Systems/browsers that keep the keyboard visible while navigating to a new page, therefore making the initial window.innerHeight value different from the actual viewport size without keyboard
Important: Doing the toggling through Input focus/blur events is out of question. I've found that on my Android phone, when the System's go-back button is pressed, the keyboard hides, but the input does not lose focus, therefore the bottom menu stays hidden.
This isn't the same question as all the others. I'm already preventing Chrome from entering text selection mode while dragging. (Edit: I only want to lock the icon/appearance, not restrict location or movement, and only between mousedown and mouseup) The issue I would like to avoid is that Chrome changes the cursor while dragging, to whatever is under the cursor (i.e.-i-beam while over text input control, hand while over hyperlink, etc).
IE and FireFox/Moz support element.setCapture() which I call in the mousedown event, that "locks" those browsers to the element so that the mouse cursor stays to whatever the cursor of that element is.. very nice. Chrome does not support that function, or anything like it, that I know of.
By watching mousemove and mouseup events on the document object instead of the element that was clicked, I'm able to still get most of the setCapture() behavior, in that I can track mouse events that happen outside of the element, and even outside the browser window. However, I'm left with one issue still, the mouse cursor changing in Chrome.
I believe you're looking for the Pointer Control Lock API, a recently introduced way for users to control the user's input device (when allowed). The big use case is gaming.
Without a secure and supported API, allowing sites to take over user input controls would be pretty disastrous (i.e. clickjacking and forced malware downloads), so if you're looking to "lock" the cursor then this is likely to be your only option.
I usually place an element over everything else with the intended cursor on mouse down and remove it on mouse up. Far from the cleanest approach but it works for me.
My implementation works great with a mouse where I can use a delegated jQuery on("mousemove","*") handler to detect when the user mouses over something and this triggers an action.
I want to do the same for multi-touch, if the user drags their finger across a child element I want a delegated touchmove handler to pick it up. However it seems like only the callback of the container element ever gets called as the finger is dragged around on that container (and over its child elements).
Is there some way I can accomplish this without writing a point-in-rect test using JS?
Fiddle here.
Notice how on a PC when you click-drag across the B DIV it gets turned red correctly.
On an iOS device (with debug console enabled) you can only get it to show up blue (by tapping inside the 'B' div). I want to be able to drag over something and "pick it up".
Behavior is also identical on a Nexus 7 Android 4.1.1 tablet with (Mobile) Chrome.
It would appear that a previous discussion provides an unsatisfactory but workable solution to my problem: