Отключение андроида хром тянуть вниз, чтобы обновить функцию
Я создал небольшое HTML5 веб-приложение для моей компании.
Это приложение отображает список элементов, и все работает нормально.
приложение в основном используется на android телефонов и Chrome в качестве браузера. Кроме того, сайт сохраняется на главном экране, поэтому Android управляет всем этим как приложением (С помощью WebView я думаю).
Chrome бета (и я думаю, что также система Android WebView) ввел "тянуть вниз, чтобы функция "обновить" (смотрите эту ссылку например).
это удобная функция, но мне было интересно, можно ли ее отключить с помощью некоторых метатегов (или javascript), потому что обновление может быть легко вызвано пользователем во время навигации по списку, и все приложение перезагружается.
также это функция, не необходимая для приложения.
Я знаю, что эта функция доступна только в бета-версии Chrome, но у меня есть ощущение, что это посадки на стабильное приложение, тоже.
спасибо!
Edit: я удалил бета-версию Chrome, и ссылка, прикрепленная к главному экрану, теперь открывается со стабильным Chrome. Таким образом, закрепленные ссылки начинаются с Chrome, а не с webview.
Edit: сегодня (2015-03-19) выпадающий список для обновления пришел в стабильный chrome.
Edit: из ответа @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;
}
}
});
Как указал @bcintegrity, я надеюсь на решение манифеста сайта (и/или мета-тег) в будущем.
кроме того, предложения для кода выше приветствуются.
13 ответов:
действие по умолчанию эффекта pull-To-refresh можно эффективно предотвратить, выполнив любое из следующих действий:
preventDefault
’ing некоторая часть последовательности касания, включая любое из следующего (в порядке наибольшего разрушения к наименьшему разрушению):
- a. весь поток касания (не идеально).
- b. все верхние overscrolling touchmoves.
- Си. Первый топ overscrolling события touchmove.
- д'. Первый топ overscrolling touchmove только тогда, когда 1) начальный touchstart произошел, когда смещение прокрутки страницы y было равно нулю и 2) touchmove вызывал бы верхний overscroll.
- применения "
touch-action: none
" для сенсорных целевых элементов, где это необходимо, отключите действия по умолчанию (включая pull-To-refresh) сенсорной последовательности.- применения "
overflow-y: hidden
" к элементу body, используя div для прокручиваемого содержимого, если это необходимо.- отключение эффекта локально через
chrome://flags/#disable-pull-to-refresh-effect
).
простое решение для 2018+
Chrome 63 (выпущен 5 декабря 2017 года) добавил свойство css, чтобы помочь именно с этим. Есть чтение через это руководство от Google чтобы получить хорошее представление о том, как вы можете справиться с этим.
вот их TL: DR
свойство CSS overscroll-behavior позволяет разработчикам переопределить поведение прокрутки переполнения браузера по умолчанию при достижении верхней или нижней части содержания. Варианты использования включают в себя отключение функции pull-To-refresh функция на мобильном телефоне, удаление overscroll glow и rubberbanding эффекты, и предотвращение прокрутки содержимого страницы, когда оно находится под модальный / наложение.
чтобы заставить его работать, все, что вы должны добавить это:
body { overscroll-behavior: contain; }
Это поддерживает Chrome, Edge и Firefox на данный момент, но я уверен, что Safari добавит его, как только они, кажется, полностью на борту с работниками службы и будущее PWA.
на данный момент Вы можете отключить эту функцию только через chrome: / / flags / #disable-pull-To-refresh-effect - откройте прямо с вашего устройства.
вы можете попытаться поймать
touchmove
события, но шансы очень малы для достижения приемлемого результата.
Я использую 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 touchmove, и если мы движемся вниз по экрану, а целевая прокрутка равна 0, мы останавливаем событие. Таким образом, нет обновления.
это означает, что мы стреляем по каждому "ходу", который может быть дорогим, но это лучшее решение, которое я нашел до сих пор ...
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.
Простой 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's 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>
лучшее решение на чистом 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
после многих часов попыток, это решение работает для меня
$("html").css({ "touch-action": "pan-down" });
найти настройка body CSS overflow-y: hidden Это самый простой способ. Если вы хотите иметь страницу приложения прокрутки, вы можете просто использовать контейнер div с прокруткой особенности.
через пару недель я узнал, что функция 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>
обратите внимание, что overflow-y не наследуется, поэтому вам нужно установить его на все элементы блока.
вы можете сделать это с помощью jQuery, просто:
$(document.body).css('overflow-y', 'hidden'); $('*').filter(function(index) { return $(this).css('display') == 'block'; }).css('overflow-y', 'hidden');
то, что я сделал, это добавить следующее к
touchstart
иtouchend
/touchcancel
события:scrollTo(0, 1)
так как chrome не прокручивается, если он не находится на позиции scrollY
0
это предотвратит chrome от выполнения тяги для обновления.если он все еще не работает, попробуйте также сделать это при загрузке страницы.
чистое решение 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);