Отключение андроида хром тянуть вниз, чтобы обновить функцию
Я создал небольшое 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);