I know that Mobile Safari won\'t fire events while in \"momentum\" (-webkit-overflow-scrolling: touch;) scrolling. But this is not entirely the same thing, because Safari ha
Had this same problem, my fix was altering between
-webkit-overflow-scrolling: touch
and
-webkit-overflow-scrolling: auto
whenever i focus/blur on inputs
I'm using jQuery.animate to scroll the window and I'm not sure if this will work if you aren't using jQuery.animate, but it worked for me. I'm just triggering the "blur" handlers on the element which doesn't actually cause the element to lose focus, it just triggers the handlers as if they had been naturally triggered by user interaction. It seems :
$content.animate(
{
scrollTop: $(this).data('originalTop')
},
{
duration: 100,
easing: 'swing',
always: function(){
var $t = $(this);
$t.trigger('blur');
}
}
);
Due to other weirdness with iOS I'm having to save the element's offset().top value as originalTop when my form loads. $content is simply a scrollable div containing my form -- eg: $('div#content').
This still seems to be plaguing webkit forms in iOS with -webkit-overflow-scrolling:touch
, also in iOS 11. Based on answers above, and since it takes focusing an input
or textearea
element for the caret to appear out of place, here's my own approach "correcting" for it
$('input').on("focus", function(){
var scrollTopVal = $(elementSelector).scrollTop();
$(elementSelector).scrollTop(scrollTopVal + 1);
$(elementSelector).scrollTop(scrollTopVal);
})
where elementSelector
points to the container element for the input elements.
Only one workaround that I was found - on scrolling event to check if input with type text is focused, set focus on some other element (for example, on button). As result, virtual keyboard and cursor will disappear. This solution is not perfect, but it doesn't look so horrible as with cursors on top of the form. Example:
$(".scrollContainer").scroll(function () {
var selected = $("input[type='text']:focus");
if (selected.length > 0) {
$('#someButton').focus();
}
}
This was a while ago and I think it was fixed on IOS11.x, of course we still need to support older versions, the suggestions above gave me a hint but none of them worked 4 my setup. I used onFocus to trigger a delayed function that adds/deletes a char to the current focused field. I'm using a flat angularJS/iOS hybrid.
on my html side
... setting up my form
<div ng-repeat="item in curReading.items" >
<label>{{item.lbl}}</label>
<input type="text"
ng-model="item.value"
class="form-control"
onFocus="if(tweak4IOS == 1) setTimeout(pirouette_4_IOS, 1000);"
placeholder="Enter Title"
/>
</div>
on my JS side the relevant code is
function pirouette_4_IOS()
{
try
{
document.activeElement.value += 'x';
document.activeElement.value = document.activeElement.value.slice(0,-1);
}
catch(err)
{
alert(err.message);
}
finally
{
tweak4IOS = 0;
}
} // --- end of pirouette_4_IOS---
...
var tweak4IOS = 0; // init the flag
Finally in the Obj-C I set the var in the keyboard pop
- (void)keyboardDidShow:(NSNotification *)sender {
CGRect frame = [sender.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
homeWeb.frame = CGRectMake(homeWeb.frame.origin.x, homeWeb.frame.origin.y,
homeWeb.frame.size.width , homeWeb.frame.size.height - frame.size.height );
self.pinBottom2.constant = frame.origin.y;
// set the JS var so it is done only when keyboard pops initially
[homeWeb stringByEvaluatingJavaScriptFromString:@"tweak4IOS=1;"];
You can fix the problem by removing the selection and setting it again. Using jQuery here is the Javascript to do so. I add the event handler when entering edit mode:
$(document).on('scroll.inline-edit', function(event) {
var selection = window.getSelection();
if (selection.rangeCount) {
var range = selection.getRangeAt(0);
selection.removeAllRanges();
selection.addRange(range);
}
});
When I exit edit mode I remove the event handler:
$(document).off('scroll.inline-edit');
This will probably also work if the event handler is always enabled.