안드로이드의 크롬 풀다운-새로 고침 기능 비활성화


135

회사를 위해 작은 HTML5 웹 응용 프로그램을 만들었습니다.

이 응용 프로그램은 항목 목록을 표시하고 모든 것이 잘 작동합니다.

이 응용 프로그램은 주로 안드로이드 폰과 Chrome에서 브라우저로 사용됩니다. 또한 사이트는 홈 화면에 저장되므로 Android 는 WebView를 사용하여 모든 것을 앱으로 관리합니다 .

Chrome 베타 (Android 시스템 WebView라고도 함) 에 '새로 고침 풀다운'기능이 도입되었습니다 ( 예 :이 링크 참조 ).

이것은 편리한 기능이지만 목록을 탐색하는 동안 사용자가 새로 고침을 쉽게 트리거 할 수 있고 전체 앱이 다시로드되기 때문에 일부 메타 태그 (또는 자바 스크립트 항목)로 비활성화 할 수 있는지 궁금합니다.

또한 이것은 응용 프로그램에 필요하지 않은 기능입니다.

이 기능은 여전히 ​​Chrome 베타에서만 사용할 수 있지만 안정적인 앱에도 적용된다는 느낌이 듭니다.

감사합니다!

편집 : Chrome 베타를 제거했으며 홈 화면에 고정 된 링크가 안정된 Chrome으로 열립니다. 따라서 고정 된 링크는 웹뷰가 아닌 Chrome으로 시작합니다.

편집 : 오늘 (2015-03-19) 풀다운 새로 고침이 안정적인 크롬에 도달했습니다.

편집 : @ Evyn 답변 에서이 링크를 따라 가면 작동하는 자바 스크립트 / jquery 코드가 있습니다.

@bcintegrity가 지적했듯이 앞으로 사이트 매니페스트 솔루션 (또는 메타 태그)이 있기를 바랍니다.

또한 위 코드에 대한 제안을 환영합니다.


18
그래 정말 짜증나 형태의 중간에 있었고 너무 멀리 위로 스크롤하여 새로 고치고 모든 것을 잃었습니다. 지연된 기본 기능입니다. 새로 고침하려면 새로 고침 아이콘을 클릭하십시오!
Brock Hensley

12
내 웹 앱 매니페스트 에서이 기능을 비활성화 할 수 있다면 좋을 것입니다. 불행히도 내 웹 앱의 모든 페이지에는 스크롤 가능한 콘텐츠가 있으므로 새로 고치지 않고 탐색하는 것이 거의 불가능합니다. 조금 진드기입니다. : /
bcintegrity

이것은 좋은 정보입니다. Pull to Refresh 기능을 비활성화하는 웹 사이트가 싫습니다. 페이지 내용에 관계없이 새로 고침을 수행하는 기능을 개발하고 싶습니다.
LS

5
웹 개발자라고 말하면 풀다운 새로 고침은 응용 프로그램을 다시로드하므로 데이터 기반 웹 사이트와 호환되지 않습니다. 사용자가 전체 페이지를 새로 고치지 않고 페이지 맨 위로 스크롤 할 수 없습니다. Chrome을 100 %지지합니다.이 기능을 제거하기를 바랍니다.
Beans

3
나는이 GC "기능"에 직면했다. 많은 웹 페이지, 다양한 형태, 손가락으로 부주의하게 끌어 당기면이 페이지의 데이터가 손실된다! 지연 기능 IMO. 기본적으로 꺼져 있어야합니다. 누가 필요한지 코딩해야합니다. 나는 왜 내 "고객"이 때때로 GC에서 데이터를 잃어 버렸는지 궁금해했다.
Ludus H

답변:


157

다음과 같이하면 새로 고침 풀 효과의 기본 동작을 효과적으로 방지 할 수 있습니다.

  1. preventDefault다음 중 하나를 포함하여 터치 시퀀스의 일부를 처리합니다 (가장 파괴적인 순서에서 가장 방해가되지 않는 순서로).
    • ㅏ. 전체 터치 스트림 (이상적이지 않음).
    • 비. 모든 오버 스크롤링 터치 이동.
    • 씨. 첫 번째 오버 스크롤 터치 이동.
    • 디. 첫 번째 오버 스크롤링 touchmove는 1) 첫 번째 터치 스타트가 페이지 y 스크롤 오프셋이 0 일 때 발생하고 2) touchmove가 상위 오버 스크롤을 유발할 때에 만 발생합니다.
  2. touch-action: none적절한 경우 터치 대상 요소에 " "를 적용 하면 터치 시퀀스의 기본 동작 (풀-리프레쉬 포함)이 비활성화됩니다.
  3. overflow-y: hidden필요한 경우 스크롤 가능한 컨텐츠에 div를 사용하여 body 요소에 “ ” 적용
  4. 를 통해 로컬로 효과 비활성화 chrome://flags/#disable-pull-to-refresh-effect ).

더보기


12
@Evyn 감사합니다. 나는 이것이 빠른 해결책이라고 믿을 수 없다! body 요소의 CSS를 overflow-y : hidden으로 설정했습니다.
bcintegrity

@Evyn에게 감사드립니다. 나는 preventDefault () 메소드를 사용하기로 결정했습니다 (첫 번째 포인트). 특히 나는 당신이 링크 한 문서 안에있는 링크 ( link ) 의 소스 코드를 흥미롭게 발견했습니다 . 질문 끝에 코드를 넣겠습니다.
Sebastiano

2
"chrome : // flags (pull-to-refresh-effect) 비활성화"는 프로그래밍 방식으로 어떻게 수행됩니까?
누군가 어딘가에

2
@SomeoneSomewhere 내가 아는 한, 불가능하지 않습니다. 크롬 설정은 사용자 만 설정할 수 있습니다. 그렇지 않으면 보안 위험이 발생할 수 있습니다.
Mike

1
스크롤 가능한 내용에 div를 사용하여 body 요소에“overflow-y : hidden”을 적용하면 나에게 도움이되었습니다.
Robin

103

2019+를위한 간단한 솔루션

Chrome 63은 CSS 속성을 추가하여 정확하게 처리합니다. 처리 방법에 대한 좋은 아이디어를 얻으려면 Google에서이 가이드를 읽어보십시오 .

TL : DR은 다음과 같습니다.

CSS 오버 스크롤 동작 속성을 통해 개발자는 컨텐츠의 상단 / 하단에 도달 할 때 브라우저의 기본 오버 플로우 스크롤 동작을 무시할 수 있습니다. 사용 사례에는 모바일에서 새로 고침 풀 기능 사용 안함, 오버 스크롤 글로우 및 고무 밴딩 효과 제거, 페이지 컨텐츠가 모달 / 오버레이 아래에서 스크롤되는 것을 방지하는 것이 포함됩니다.

작동 시키려면 CSS에서 추가하면됩니다.

body {
  overscroll-behavior: contain;
}

또한 현재는 Chrome, Edge 및 Firefox 에서만 지원 되지만 서비스 담당자와 PWA의 미래에 온전한 사파리로 Safari가 곧 추가 할 것으로 확신합니다.


16
이것은 가장 최신 anwser
colxi

다른 사람이 "홈 화면에 추가"크롬 배너의 모양이 지연되는 것을 보았습니까?
Nathaniel Hill

2
비활성화하기 위해 html 요소에 적용해야했습니다
Jakob Eriksson

1
이것은 Android에서만 작동합니다. IO의 Chrome에서 여전히 빛 효과 + 기본 풀을 새로 고침
Fky

developers.google.com/web/updates/2017/11/overscroll-behavior 이 링크는 더 잘 설명 할 수 있습니다.
arung86

15

현재 chrome : // flags / # disable-pull-to-refresh-effect 를 통해서만이 기능을 비활성화 할 수 있습니다 -기기에서 직접 엽니 다.

touchmove이벤트 를 잡으려고 시도 할 수는 있지만 수용 가능한 결과를 얻을 가능성은 매우 적습니다.


1
Kevin에게 답변을 주셔서 감사합니다. 사용자에게 의존하지 않는 것을 찾고 있었기 때문에 이것을 받아 들일 수 없었습니다. 그러나이 방법은 효과가 있으므로 충분한 평판을 얻으면 답변을 찬성합니다.
Sebastiano

이것이 최선의 해결책 인 것처럼 유감입니다. 미래에 플래그 설정이 변경되거나 다른 사이트에서 pull을 사용하여 새로 고치기를 원할 경우 어떻게해야합니까? :(.
user1063287

1
Google CEO가이 내용을 읽고 있다면이 기능을 제거하십시오. 그것은 쉽고 포괄적으로 비활성화 될 수없는 것 같습니다. 제 생각에는 모든 웹 응용 프로그램이 원하는 웹 응용 프로그램 "기능"입니다.
user1063287

8

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;
});

여기서 우리가하는 일은 touchmove의 y 방향을 찾는 것입니다. 화면 아래로 이동하고 대상 스크롤이 0이면 이벤트를 중지합니다. 따라서 새로 고침이 없습니다.

이것은 우리가 모든 '이동'을 시작한다는 것을 의미합니다. 이는 비쌀 수 있지만 지금까지 내가 찾은 최고의 솔루션입니다 ...


2
새로 고침 풀이 트리거 될 가능성이 없으므로 사용자가 아래로 스크롤하자마자 시청을 중단하는 것이 안전합니다. 마찬가지로이면 scrolltop > 0이벤트가 트리거되지 않습니다. 구현에서는 touchmove이벤트 touchstart만 에 바인딩합니다 scrollTop <= 0. 사용자가 아래로 스크롤하자마자 바인딩을 해제합니다 ( initialY >= e.touches[0].clientY). 사용자가 위로 스크롤하면 ( previousY < e.touches[0].clientY) 전화 preventDefault합니다.
Nicolas Bouliane

7

여러 시간 동안 노력한 후에이 솔루션은 저에게 효과적입니다.

$("html").css({
    "touch-action": "pan-down"
});

이를 위해 jQuery를 사용할 필요가 없습니다. CSS 코드 파일에 "touch-action : pan-down"을 추가하십시오.
Keegan Teetaert

1
CSS에서 이것을 사용하십시오 :html{touch-action:pan-down}
csandreas1

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이벤트가 트리거되지 않습니다. 내 구현에서 나는 touchstart에 touchmove 이벤트를 바인딩합니다 scrollTop <= 0. 사용자가 아래로 스크롤하자마자 바인딩을 해제합니다 ( initialY >= e.touches[0].clientY). 사용자가 위로 스크롤하면 ( previousY < e.touches[0].clientY) 전화 preventDefault()합니다.

이렇게하면 스크롤 이벤트를 불필요하게 시청하지 않아도되지만 오버 스크롤은 차단됩니다.

jQuery

jQuery를 사용하는 경우 테스트되지 않은 기능 입니다. elementjQuery 요소입니다.

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에서도 마찬가지입니다.


나는 e.originalEvent.touches[0].clientY이 일을하기 위해 사용해야 했다. 다시로드를 막을 여전히 논리에 어려움을 겪고 있습니다. 지금은 무작위로 스크롤을 방지하는 것 같습니다 ... 올바른 방향으로 힌트를 주셔서 감사합니다!
토마스

지시어는 어떤 요소에 추가됩니까?
Fizzix

AngularJS 지시문은 저에게 효과적이었습니다. 우리는 Framework7과 Angular를 함께 사용하고 있으며 (추천하지는 않음) scrollTop의 올바른 동작을 차단하는 것이 있습니다. 그래서 blockScroll이 요소에 추가 될 때 수정해야했습니다. 그러나 단지 감사를 표하고 싶었다!
더스틴 젠슨

5

간단한 자바 스크립트

표준 자바 스크립트를 사용하여 구현했습니다. 간단하고 쉬운 구현. 붙여 넣기 만하면 제대로 작동합니다.

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

이것은 Chrome에서 매우 효과적이지만 페이지 상단에서 div를 스크롤 할 때 Safari / iOS 9.2에서 스크롤 업하는 데 문제가 발생했습니다 ( 여기에서 재현 됨 ). 나는 위의 Evynbody: {overflow-y:hidden}트릭을 사용하게되었습니다 .
sennett

크롬에서는 작동하지 않지만 파이어 폭스 예제에서는 작동합니다. embed.plnkr.co/rqbOVSOkKyhAgoHK2sEP 는 모바일에서만 열림
vijay

붙여 넣은 링크는 내 안드로이드 모바일에서도 크롬에서 작동했습니다. 당겨서 새로 고칠 수 없습니다. 어떤 버전의 android / ios를 테스트에 사용하고 있습니까?
Sacky San

2
Chrome 56에서는 수동 : false를 설정해야 작동합니다. document.addEventListener ( 'touchstart', touchstartHandler, {수동 : false}); document.addEventListener ( 'touchmove', touchmoveHandler, {수동 : false});
Anton Kuzmin

4

순수한 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


크롬을 사용하여 모바일에서 실제로 테스트 했습니까?
Gregor Voinov


3

본문 CSS overflow-y : hidden을 설정하는 것이 가장 간단한 방법이라는 것을 알았 습니다. 스크롤 응용 프로그램 페이지를 원한다면 스크롤 기능이있는 div 컨테이너를 사용할 수 있습니다.


줄로 고칠 수는 없지만 매력처럼 작동합니다. 많은 감사합니다!
Ignacio Ara

2

overflow-y는 상속되지 않으므로 모든 블록 요소에 설정해야합니다.

jQuery를 사용하여 간단히 다음을 수행 할 수 있습니다.

        $(document.body).css('overflow-y', 'hidden'); 
        $('*').filter(function(index) {
            return $(this).css('display') == 'block';
        }).css('overflow-y', 'hidden');

다른 답변 중에서도 이것이 실제로 도움이됩니다. 감사. 이 줄을 CSS에 추가하십시오. body {overflow-y : 숨김; }
Sarin JS

2

몇 주 후에 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>


1

순수한 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);

0

내가 한 것은 touchstartand touchend/ touchcancelevents에 다음을 추가하는 것입니다 .

scrollTo(0, 1)

크롬이 scrollY 위치에 있지 않으면 스크롤되지 않기 때문에 0 새로 고침을 수행하지 .

여전히 작동하지 않으면 페이지가로드 될 때도 시도하십시오.


0

이 문제로 풀다운에서 새로 고침 문제를 해결했습니다.

html, body {
    width: 100%;
    height: 100%;
    overflow: hidden;
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.