Отключение функции выключения Android-хром
Я создал небольшое веб-приложение HTML5 для своей компании.
Это приложение отображает список элементов, и все работает нормально.
Приложение в основном используется на телефонах Android и Chrome в качестве браузера. Кроме того, сайт сохраняется на главном экране, поэтому Android управляет всем приложением (с помощью WebView, я думаю,).
Chrome Beta (и я также думаю, что Android System WebView) добавила функцию "pull down to refresh" (См. эту ссылку, например).
Это удобная функция, но мне было интересно, можно ли ее отключить с помощью метатега (или javascript), потому что обновление может быть легко вызвано пользователем во время навигации по списку, и все приложение перезагружается.
Также это функция, не требуемая приложением.
Я знаю, что эта функция по-прежнему доступна только в бета-версии Chrome, но у меня есть ощущение, что она тоже приземляется на стабильное приложение.
Спасибо!
Изменить: я удалил бета-версию Chrome, и ссылка, прикрепленная к главному экрану, теперь открывается стабильным Chrome. Таким образом, привязанные ссылки начинаются с Chrome, а не с веб-просмотром.
Изменить: сегодня (2015-03-19) переход к обновлению достиг стабильного хрома.
Изменить: из ответа @Evyn Я следую этой ссылке и получил этот код javascript/jquery, который работает.
var lastTouchY = 0;
var preventPullToRefresh = false;
$('body').on('touchstart', function (e) {
if (e.originalEvent.touches.length != 1) { return; }
lastTouchY = e.originalEvent.touches[0].clientY;
preventPullToRefresh = window.pageYOffset == 0;
});
$('body').on('touchmove', function (e) {
var touchY = e.originalEvent.touches[0].clientY;
var touchYDelta = touchY - lastTouchY;
lastTouchY = touchY;
if (preventPullToRefresh) {
// To suppress pull-to-refresh it is sufficient to preventDefault the first overscrolling touchmove.
preventPullToRefresh = false;
if (touchYDelta > 0) {
e.preventDefault();
return;
}
}
});
Ответы
Ответ 1
Действие по умолчанию для эффекта pull-to-refresh можно эффективно предотвратить, выполнив одно из следующих действий:
-
preventDefault
некоторых частей последовательности касаний, включая любое из следующего (в порядке от наиболее разрушительного до наименее разрушительного): - а. Весь сенсорный поток (не идеальный).
- б. Все верхние сверхскоростные сенсорные движения.
- с. Первый верхний перебегающий сенсорный ход.
- д. Первое касание с верхней прокруткой только тогда, когда 1) начальное касание произошло, когда смещение прокрутки страницы y было равно нулю, и 2) касание переместило бы верхнюю прокрутку.
- Применение "
touch-action: none
" к элементам, нацеленным на прикосновение, где это уместно, отключение действий по умолчанию (в том числе pull-to-refresh) последовательности касаний. - Применяя "
overflow-y: hidden
" к элементу body, используя div для прокручиваемого содержимого, если это необходимо. - Отключение эффекта локально с помощью
chrome://flags/#disable-pull-to-refresh-effect
).
Узнать больше
Ответ 2
Простое решение для 2019+
Chrome 63 (выпущен 5 декабря 2017 года) добавил свойство css, чтобы помочь именно с этим. Прочтите это руководство от Google, чтобы получить представление о том, как с ним справиться.
Вот их TL: DR
Свойство CSS overscroll-поведения позволяет разработчикам переопределять поведение прокрутки переполнения браузера по умолчанию при достижении верха/низа контента. Варианты использования включают в себя отключение функции "pull-to-refresh" на мобильном устройстве, устранение эффектов свечения при избыточной прокрутке и резиновой полосы, а также предотвращение прокрутки содержимого страницы, если оно находится ниже модального/наложения.
Чтобы все заработало, все, что вам нужно добавить, это в вашем CSS:
body {
overscroll-behavior: contain;
}
На данный момент он также поддерживается только Chrome, Edge и Firefox, но я уверен, что Safari добавит его в ближайшее время, так как они, похоже, полностью совместимы с работниками сферы обслуживания и будущим PWA.
Ответ 3
В настоящий момент вы можете отключить эту функцию только с помощью chrome://flags/#disable-pull-to-refresh-effect - открыть прямо с вашего устройства.
Вы можете попытаться поймать события touchmove
, но шансы очень тонкие, чтобы достичь приемлемого результата.
Ответ 4
Я использую MooTools, и я создал класс для отключения обновления на целевом элементе, но суть его (родной JS):
var target = window; // this can be any scrollable element
var last_y = 0;
target.addEventListener('touchmove', function(e){
var scrolly = target.pageYOffset || target.scrollTop || 0;
var direction = e.changedTouches[0].pageY > last_y ? 1 : -1;
if(direction>0 && scrolly===0){
e.preventDefault();
}
last_y = e.changedTouches[0].pageY;
});
Все, что мы делаем, это найти направление y сенсорной кнопки, и если мы движемся вниз по экрану, а целевой свиток - 0, мы остановим это событие. Таким образом, обновление не обновляется.
Это означает, что мы стреляем в каждое "движение", которое может быть дорогостоящим, но это лучшее решение, которое я нашел до сих пор...
Ответ 5
AngularJS
Я успешно отключил его с помощью этой директивы AngularJS:
//Prevents "pull to reload" behaviour in Chrome. Assign to child scrollable elements.
angular.module('hereApp.directive').directive('noPullToReload', function() {
'use strict';
return {
link: function(scope, element) {
var initialY = null,
previousY = null,
bindScrollEvent = function(e){
previousY = initialY = e.touches[0].clientY;
// Pull to reload won't be activated if the element is not initially at scrollTop === 0
if(element[0].scrollTop <= 0){
element.on("touchmove", blockScroll);
}
},
blockScroll = function(e){
if(previousY && previousY < e.touches[0].clientY){ //Scrolling up
e.preventDefault();
}
else if(initialY >= e.touches[0].clientY){ //Scrolling down
//As soon as you scroll down, there is no risk of pulling to reload
element.off("touchmove", blockScroll);
}
previousY = e.touches[0].clientY;
},
unbindScrollEvent = function(e){
element.off("touchmove", blockScroll);
};
element.on("touchstart", bindScrollEvent);
element.on("touchend", unbindScrollEvent);
}
};
});
Безопасно останавливать просмотр, как только пользователь прокручивается вниз, так как притяжение к обновлению не имеет шансов быть вызванным.
Аналогично, если scrolltop > 0
, событие не будет запущено. В моей реализации я привязываю событие touchmove к touchstart, только если scrollTop <= 0
. Я отсоединяю его, как только пользователь прокручивается вниз (initialY >= e.touches[0].clientY
). Если пользователь прокручивается (previousY < e.touches[0].clientY
), я вызываю preventDefault()
.
Это избавляет нас от просмотра событий прокрутки без необходимости, но блокирует перекрестную проверку.
JQuery
Если вы используете jQuery, это непроверенный эквивалент. element
является элементом jQuery:
var initialY = null,
previousY = null,
bindScrollEvent = function(e){
previousY = initialY = e.touches[0].clientY;
// Pull to reload won't be activated if the element is not initially at scrollTop === 0
if(element[0].scrollTop <= 0){
element.on("touchmove", blockScroll);
}
},
blockScroll = function(e){
if(previousY && previousY < e.touches[0].clientY){ //Scrolling up
e.preventDefault();
}
else if(initialY >= e.touches[0].clientY){ //Scrolling down
//As soon as you scroll down, there is no risk of pulling to reload
element.off("touchmove");
}
previousY = e.touches[0].clientY;
},
unbindScrollEvent = function(e){
element.off("touchmove");
};
element.on("touchstart", bindScrollEvent);
element.on("touchend", unbindScrollEvent);
Естественно, то же самое можно достичь и с чистым JS.
Ответ 6
После многих часов попыток это решение работает для меня
$("html").css({
"touch-action": "pan-down"
});
Ответ 7
Простой Javascript
Я реализовал с использованием стандартного javascript. Простая и простая в использовании. Просто вставьте, и он отлично работает.
<script type="text/javascript"> //<![CDATA[
window.addEventListener('load', function() {
var maybePreventPullToRefresh = false;
var lastTouchY = 0;
var touchstartHandler = function(e) {
if (e.touches.length != 1) return;
lastTouchY = e.touches[0].clientY;
// Pull-to-refresh will only trigger if the scroll begins when the
// document Y offset is zero.
maybePreventPullToRefresh =
window.pageYOffset == 0;
}
var touchmoveHandler = function(e) {
var touchY = e.touches[0].clientY;
var touchYDelta = touchY - lastTouchY;
lastTouchY = touchY;
if (maybePreventPullToRefresh) {
// To suppress pull-to-refresh it is sufficient to preventDefault the
// first overscrolling touchmove.
maybePreventPullToRefresh = false;
if (touchYDelta > 0) {
e.preventDefault();
return;
}
}
}
document.addEventListener('touchstart', touchstartHandler, false);
document.addEventListener('touchmove', touchmoveHandler, false); });
//]]> </script>
Ответ 8
Лучшее решение для чистого CSS:
body {
width: 100%;
height: 100%;
display: block;
position: absolute;
top: -1px;
z-index: 1;
margin: 0;
padding: 0;
overflow-y: hidden;
}
#pseudobody {
width:100%;
height: 100%;
position: absolute;
top:0;
z-index: 2;
margin: 0;
padding:0;
overflow-y: auto;
}
Смотрите эту демонстрацию: https://jsbin.com/pokusideha/quiet
Ответ 9
Я считаю, что настройка
body CSS overflow-y: hidden - самый простой способ. Если вы хотите иметь прокручиваемую страницу приложения, вы можете просто использовать контейнер div с функциями прокрутки.
Ответ 10
За пару недель я узнал, что функция javascript, которую я использовал для отключения действия обновления Chrome, больше не будет работать. Я решил это решить:
$(window).scroll(function() {
if ($(document).scrollTop() >= 1) {
$("html").css({
"touch-action": "auto"}
);
} else {
$("html").css({
"touch-action": "pan-down"
});
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
Ответ 11
Обратите внимание, что overflow-y не наследуется, поэтому вам нужно установить его на ВСЕ блочные элементы.
Вы можете сделать это с помощью jQuery, просто:
$(document.body).css('overflow-y', 'hidden');
$('*').filter(function(index) {
return $(this).css('display') == 'block';
}).css('overflow-y', 'hidden');
Ответ 12
То, что я сделал, это добавить следующие события touchstart
и touchend
/touchcancel
:
scrollTo(0, 1)
Поскольку хром не прокручивается, если он не находится в позиции scrollY 0
, это предотвратит выполнение chrome для обновления.
Если он все еще не работает, попробуйте сделать это, когда страница загружается.
Ответ 13
Решение Pure js.
// Prevent pull refresh chrome
var lastTouchY = 0;
var preventPullToRefresh = false;
window.document.body.addEventListener("touchstart", function(e){
if (e.touches.length != 1) { return; }
lastTouchY = e.touches[0].clientY;
preventPullToRefresh = window.pageYOffset == 0;
}, false);
window.document.body.addEventListener("touchmove", function(e){
var touchY = e.touches[0].clientY;
var touchYDelta = touchY - lastTouchY;
lastTouchY = touchY;
if (preventPullToRefresh) {
// To suppress pull-to-refresh it is sufficient to preventDefault the first overscrolling touchmove.
preventPullToRefresh = false;
if (touchYDelta > 0) {
e.preventDefault();
return;
}
}
}, false);
Ответ 14
Я решил проблему выпадающего меню с помощью этого:
html, body {
width: 100%;
height: 100%;
overflow: hidden;
}