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


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에서 스크롤 업하는 데 문제가 발생했습니다 ( 여기에서 재현 됨 ). 나는 위의 Evyn 의 body: {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.