Mobile Safari - входной карет не прокручивается вместе с прокруткой переполнения: touch

Я знаю, что Mobile Safari не будет запускать события во время прокрутки "импульс" (-webkit-overflow-scrolling: touch;). Но это не совсем одно и то же, потому что Safari обрабатывает (мигающую) каретку внутреннего ввода.

<div id="container">
    <input type="text" />
    <div class="filling"></div>
</div>

#container {
    position: absolute;
    top: 20px;
    bottom: 20px;
    width: 50%;
    -webkit-overflow-scrolling: touch;
    overflow-y: auto;
    border: 1px solid black;
}

input {
    margin-top: 60vh;
}

.filling {
    height: 200vh;
}

Попробуйте эту скрипту на своем устройстве (сфокусируйте вход и затем прокрутите): https://jsfiddle.net/gabrielmaldi/n5pgedzv

Проблема также возникает, когда вы держите палец нажатой (т.е. не только при подаче импульса и отпускании): карет не прокручивается.

Очевидно, я не хочу отключать прокрутку переполнения, если нет возможности исправить каретку, чтобы она прокручивалась правильно, было бы нормально ее скрыть.

Спасибо

Ответ 2

Только одно обходное решение, которое я нашел - при прокрутке события, чтобы проверить, сфокусирован ли вход с типом текста, установите фокус на какой-либо другой элемент (например, на кнопке). В результате виртуальная клавиатура и курсор исчезнут. Это решение не идеально, но оно не выглядит таким ужасным, как с курсорами поверх формы. Пример:

$(".scrollContainer").scroll(function () {
  var selected = $("input[type='text']:focus");
  if (selected.length > 0) {
      $('#someButton').focus();
  }
}

Ответ 3

Я потратил много времени, пытаясь понять это, и не имел успеха с другими идеями, упомянутыми здесь.

Одна вещь, которую я заметил, заключается в том, что даже если курсор будет плавать за пределами ввода, как только вы начнете вводить текст на экранной клавиатуре, курсор вернется в правильное положение.

Это дало мне идею - возможно, используя некоторый JS-код, я мог бы изменить значение ввода, а затем быстро изменить его на текущее значение. Возможно, это заставит курсор выровнять себя так же, как при ручной настройке.

Я тестировал его, и это сработало. Вот как выглядит код:

       myIScroll.scrollToElement(element, scrollTime); // any scroll method call
       var scrollTime = 400;
       if (element.type && element.type == 'text') {
          var currentValue = $(element).val();
          $timeout(function(){
            $(element).val(currentValue + 'a').val(currentValue);
          }, scrollTime);
        }

Ответ 4

Это действительно ошибка в недавно выпущенном iOS 11.I разрешил проблему для модального, изменив css:

.modal {
  position:fixed;
  overflow-y: scroll;
  bottom: 0;
  left: 0;
  right: 0;
  top: 0;
  z-index: 99;
}

body {
  height: 100%;
  width:100%;
  overflow: hidden;
  position:fixed;
}

Ответ 5

Если бы эта же проблема, мое исправление изменялось между

-webkit-overflow-scrolling: touch

и

-webkit-overflow-scrolling: auto

всякий раз, когда я фокусирую/размываю на входы

Ответ 6

Вы можете устранить проблему, удалив выделение и снова установив его. Использование jQuery здесь Javascript для этого. Я добавляю обработчик событий при входе в режим редактирования:

        $(document).on('scroll.inline-edit', function(event) {
            var selection = window.getSelection();
            if (selection.rangeCount) {
                var range = selection.getRangeAt(0);
                selection.removeAllRanges();
                selection.addRange(range);
            }
        });

Когда я выхожу из режима редактирования, я удаляю обработчик событий:

        $(document).off('scroll.inline-edit');

Это, вероятно, также будет работать, если обработчик событий всегда включен.

Ответ 7

Я использую jQuery.animate для прокрутки окна, и я не уверен, что это сработает, если вы не используете jQuery.animate, но это сработало для меня. Я просто запускаю обработчики "размытия" на элементе, который фактически не приводит к тому, что элемент теряет фокус, он просто запускает обработчики, как если бы они были естественным образом вызваны взаимодействием с пользователем. Кажется:

$content.animate(
    {
        scrollTop: $(this).data('originalTop')
    }, 
    {
        duration: 100,
        easing: 'swing',
        always: function(){
            var $t = $(this);
            $t.trigger('blur');
        }
    }
);

Из-за другой странности с iOS мне нужно сохранить смещение элемента(). Верхнее значение как originalTop, когда моя форма загружается. $content - это просто прокручиваемый div, содержащий мою форму - например: $('div # content').

Ответ 8

Это все еще, кажется, преследует формы webkit в iOS с помощью -webkit-overflow-scrolling:touch, также в iOS 11. Исходя из ответов выше, и поскольку он фокусирует элемент input или textearea для того, чтобы каретка выглядела неуместной, здесь мой собственный подход "исправления" для него

$('input').on("focus", function(){
    var scrollTopVal =  $(elementSelector).scrollTop();
    $(elementSelector).scrollTop(scrollTopVal + 1);
    $(elementSelector).scrollTop(scrollTopVal);
})

где elementSelector указывает на элемент контейнера для входных элементов.

Ответ 9

Это было давно, и я думаю, что это было исправлено на IOS11.x, конечно, нам все равно нужно поддерживать более старые версии, приведенные выше предложения дали мне подсказку, но ни одна из них не работала 4 моей установки. Я использовал onFocus для запуска функции с задержкой, которая добавляет/удаляет char в текущее сфокусированное поле. Я использую плоский угловой гибрид JS/iOS.

на моей стороне html

... 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>

на моей стороне JS соответствующий код

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

Наконец, в Obj-C я устанавливаю var в клавиатуре 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;"];