Предотвращение прокрутки в мобильном браузере без предотвращения ввода фокуса

Я использую preventDefault () на сенсорном объекте в документе, чтобы предотвратить прокрутку страницы. К сожалению, это слишком сильно мешает. Пользователь больше не может фокусироваться на вводе (и откройте мягкую клавиатуру). Используя jQuery focus (), я могу сфокусироваться на входе на сенсорный старт. Это открывает мягкую клавиатуру на iOS (большую часть времени), но никогда на Android.

Предпосылки :

У меня есть веб-страница, которую я хочу сделать так же, как мобильное приложение, насколько это возможно. Я действительно очень заинтересован в Android и iOS, но в любом форм-факторе. Я начинаю с того, что содержимое на странице имеет тот же размер, что и размер экрана. Это приятно, пока пользователь не поместит свой палец на страницу. Мне нужно предотвратить прокрутку пользователя. Следующий код выполняет это, но несколько по-разному в двух операционных системах.

$(document).on('touchstart', function(e) { e.preventDefault(); }); 

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

На Android предотвращает обнаружение удобного хака, который я использую, чтобы скрыть адресную строку. Android-браузеры начинаются с видимой адресной строки, но по мере того, как пользователь прокручивает страницу вниз, она исчезает. Чтобы программно заставить браузер скрыть адресную строку, просто добавьте эту строку кода в свою функцию под нагрузкой.

 $('html, body').scrollTop(1); 

Это хакерский (но и единственный) способ сказать браузеру Android, который мы прокрутили, и адресная строка больше не нужна.

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

Таким образом, обе ОС имеют вескую причину, чтобы этот метод preventDefault () вызывал каждый штрих-код документа, но он слишком мешает. Нажатие на поле ввода ничего не делает. Использование вызова функции jQuery focus () может помочь, но только открывает мягкую клавиатуру на iOS, а не на Android.

 $('input').on('touchstart', function() { $(this).focus(); }); 

Как я могу предотвратить прокрутку страницы, но использовать встроенную функцию браузера для того, чтобы дать фокус полям ввода?

Примечание. Этот код

 $(document).on('touchstart', function(e) { if (e.target.nodeName !== 'INPUT') { e.preventDefault(); } }); 

Является недостатком, поскольку пользователь все еще может прокручивать страницу до тех пор, пока исходное касание возникает из поля ввода.

Solutions Collecting From Web of "Предотвращение прокрутки в мобильном браузере без предотвращения ввода фокуса"

Я действительно решил эту проблему в другом проекте, забыл об этом и запомнил это большую часть пути, набрав это.

Они – это просто сделать это на touchmove.

 $(document).on('touchmove', function(e) { e.preventDefault(); }); 

Тем не менее, preventDefault на touchstart делает всевозможные приятные вещи, такие как предотвращение создания меню сохранения изображений на жестком слайде. Мои проекты также включают это.

 $(document).on('touchstart', function(e) { if (e.target.nodeName !== 'INPUT') { e.preventDefault(); } }); 

Если у кого-то есть предложения по дополнительному контенту или как переформатировать это, чтобы он мог достичь большей аудитории, это было бы здорово. Я никогда не видел содержания, которое у меня здесь, в одном месте, поэтому я чувствовал, что это должно быть на SO.

Объедините их!

 // prevent scrolling from outside of input field $(document).on('touchstart', function(e) { if (e.target.nodeName !== 'INPUT') { e.preventDefault(); } }); // prevent scrolling from within input field $(document).on('touchmove', function(e) { if (e.target.nodeName == 'INPUT') { e.preventDefault(); } }); 

Это, вероятно, тоже не идеально, и я особенно обеспокоен тем, что первая функция предотвратит последующие ссылки, но я оставлю ее другим, чтобы провести обширные тесты.

Простой ответ на ваш вопрос заключается не в том, чтобы использовать «preventDefault» вместо использования свойства cinter-events pointer-events, чтобы отключить прокрутку элемента, который прокручивается.

CSS для ваших входных данных:

 input { pointer-events: auto !important; } 

Прослушиватель событий:

 document.body.addEventListener('touchstart', function(e) { if (e.target.nodeName === 'INPUT') { this.style.pointerEvents = 'none'; } }); 

Вам нужно будет сбросить указатели-события, когда вы размываете вход.

 document.body.pointerEvents = 'auto'; 

+1 Хороший вопрос