ipad safari : 스크롤링 및 바운스 효과 비활성화?


126

저는 브라우저 기반 앱에서 작업 중이며 현재 ipad safari 브라우저 용으로 개발 및 스타일링 중입니다.

ipad에서 두 가지를 찾고 있습니다. 필요하지 않은 페이지에 대해 세로 스크롤을 비활성화하려면 어떻게해야합니까? & Elastic Bounce 효과를 어떻게 비활성화 할 수 있습니까?


나를 위해 일하고 현재 ( stackoverflow.com/a/51176339/1979180 )
frage

답변:


157

매우 오래된 iOS 장치 용으로 개발하지 않는 한이 답변은 더 이상 적용되지 않습니다. 다른 솔루션을 참조하십시오.


2011 답변 : iOS Safari 내에서 실행되는 웹 / html 앱의 경우

document.ontouchmove = function(event){
    event.preventDefault();
}

iOS 5의 경우 document.ontouchmove 및 iOS 5의 스크롤링 을 고려할 수 있습니다.

2014 년 9 월 업데이트 : https://github.com/luster-io/prevent-overscroll 에서보다 철저한 접근 방식을 찾을 수 있습니다 . 이것과 많은 유용한 웹앱 조언은 http://www.luster.io/blog/9-29-14-mobile-web-checklist.html을 참조하십시오 .

2016 년 3 월 업데이트 : 마지막 링크는 더 이상 활성화되지 않습니다. https://web.archive.org/web/20151103001838/http://www.luster.io/blog/9-29-14-mobile-web-checklist 참조 대신 보관 된 버전의 경우 .html . 지적 해 주신 @falsarella에게 감사드립니다.


1
iOS Safari 내에서 웹 앱을 실행하고 있으며 ontouchmove 이벤트를 비활성화하려고 시도했지만 신중하게 수행하면 바운스 효과를 볼 수 있습니다. (iOS 5)
Nilesh

7
바운스 효과를 비활성화하면 어떨까요 ...?
Yuval A.

6
이 접근 방식의 문제는 dom의 스크롤 가능한 div가 더 이상 스크롤되지 않는다는 것입니다. DOM 설정에 따라이 문제를 해결할 수있는 방법이 있습니다.
huesforalice 2014 년

3
여기에 많은 사람들이 이것을 사용하는 동안 div를 스크롤하는 것에 대해 질문하고 있습니다. 그래서 div를 스크롤 가능하게 만들 onTouchMove: function(e) { e.stopPropagation(); e.stopImmediatePropagation(); } 려면 이벤트가 몸에 닿는 것을 방지하지만 몸은 탄력이없는 상태로 유지됩니다. 편집 : 이것은 $ ( 'div'). on ( 'touchmove', ... onTouchMove);
매트 Kenefick

1
마지막 링크 나를 위해 작동하지 않았다 @OskarAustegard,하지만 웹 아카이브의 내용을 찾을 수 : web.archive.org/web/20151103001838/http://www.luster.io/blog/...
falsarella

116

body / html의 위치를 ​​고정으로 변경할 수도 있습니다.

body,
html {
  position: fixed;
}

2
이것은 실제로 iPad iOS 8.2 Safari에서 매우 잘 작동했습니다. 더 이상 바운스 효과가 없습니다.
Akseli Palén 2015-06-05

3
가장 좋은 방법은 내가 지금까지 본 적이 그렇게하기
hildende

8
위치 : 절대 및 모든면이 0 (전체 화면 div를 만들기 위해)으로 설정된 항목을 배치하려는 경우 작동하지 않습니다. 전체 문서가 아무것도 축소되지 않습니다.
riv

4
이 페이지를 사용하면 페이지 맨 위로 이동하여 입력에 집중합니다. 이 문제를 해결하는 방법을 알고 있습니까?
Julie

1
@riv 추가 너비 : 100 %; height : body와 html 모두에게 100 % 도움이되었습니다.
Tim

58

최신 모바일 브라우저에서 스크롤을 방지하려면 passive : false를 추가해야합니다. 이 해결책을 찾을 때까지 나는 이것을 작동시키기 위해 머리카락을 뽑아 내고있었습니다. 나는 이것이 인터넷의 다른 한 곳에서만 언급 된 것을 발견했습니다.

function preventDefault(e){
    e.preventDefault();
}

function disableScroll(){
    document.body.addEventListener('touchmove', preventDefault, { passive: false });
}
function enableScroll(){
    document.body.removeEventListener('touchmove', preventDefault);
}


7
없이는 { passive: false }확실히 작동하지 않습니다 !!! StackOverflow 친구에 오신 것을 환영합니다
Ser

2
이 솔루션을 제공해 주셔서 감사합니다!
Paul Z.

6
이것은 정답입니다. 여기에서 설명을 볼 수 있습니다. developer.mozilla.org/en-US/docs/Web/API/EventTarget/… Chrome 54 touchmove가 기본적으로 true로 설정되어 preventDefault 호출이 무시됨을 의미합니다. 그렇기 때문에 {passive : false}를 전달해야하므로 preventDefault 호출이 무시되지 않습니다.
derickito

1
JS에서 함수를 선언하고 있습니다. 그러나 제안 된대로 작동하도록 요소에서이 함수를 어떻게 호출합니까?
ikwyl6

4
모든 종류의 스크롤링을 비활성화하려는 경우 유용합니다. 그러나 본문에서만 스크롤을 비활성화하고 요소를 스크롤 할 수있는 가능성을 유지하려면 overflow-y: scroll어떻게해야합니까? 예를 들어, 본체보다 뷰 높이가 더 높은 모달이 있습니다.
Calsal 2010 년

7

이 jQuery 코드 조각을 사용하여 다음을 수행 할 수 있습니다.

$(document).bind(
      'touchmove',
          function(e) {
            e.preventDefault();
          }
);

이렇게하면 페이지에서 발생하는 수직 스크롤 및 바운스 백 효과를 차단합니다.


11
이것은 자바 스크립트가 아니라 jQuery입니다. 모든 사람이 그 프레임 워크를 사용하는 것은 아닙니다.
inta 2014

내가 어떻게 수평 바운스 또는 스크롤 중지 할 수 있습니다
피델 카스트로

가로 스크롤을 사용하면 overflow-x : hidden을 적용하여 CSS만으로 비활성화 할 수도 있습니다. 메인 컨테이너에. 최신 버전의 사파리에서는 바운스 효과를 비활성화 할 수 없습니다. 모바일 장치 브라우저의 기본 기능입니다.
Alessandro Incarnati 2014 년

6
@inta 이것은 실제로 자바 스크립트라고 말하는 것입니다. 순수한 자바 스크립트가 아닙니다.
Ben Lorantfy

6
overflow: scroll;
-webkit-overflow-scrolling: touch;

컨테이너에서 요소 내부에 바운스 효과를 설정할 수 있습니다.

출처 : http://www.kylejlarson.com/blog/2011/fixed-elements-and-scrolling-divs-in-ios-5/


1
함께 overflow:hidden<body>이 여전히 최고의 솔루션입니다. 그러나 키보드를 열거 나 화면 하단을 미끄러지면 더 이상 작동하지 않습니다.
Fabian von Ellerts

입력 onfocus 제거 오버플로
user956584

4

나는 이것이 약간 오프 피스트라는 것을 알고 있지만 Swiffy를 사용하여 Flash를 대화 형 HTML5 게임으로 변환하고 동일한 스크롤 문제를 발견했지만 작동하는 솔루션을 찾지 못했습니다.

내가 가진 문제는 Swiffy 스테이지가 전체 화면을 차지하고있어서로드 되 자마자 문서 touchmove 이벤트가 트리거되지 않았다는 것입니다.

같은 이벤트를 Swiffy 컨테이너에 추가하려고하면 스테이지가로드되는 즉시 교체되었습니다.

결국 나는 스테이지 내의 모든 DIV에 touchmove 이벤트를 적용하여 문제를 해결했습니다. 이러한 div도 계속 변경되므로 계속 확인해야했습니다.

이것은 잘 작동하는 내 솔루션이었습니다. 나와 동일한 솔루션을 찾으려는 다른 사람에게 도움이 되었기를 바랍니다.

var divInterval = setInterval(updateDivs,50);
function updateDivs(){
$("#swiffycontainer > div").bind(
    'touchmove',
     function(e) {
        e.preventDefault();
    }
);}

이 아이 패드의 전체 스크롤을 비활성화
피델 카스트로에게

3

ipad safari를 제거하려면 코드 : 스크롤링 비활성화 및 바운스 효과

   document.addEventListener("touchmove", function (e) {
        e.preventDefault();
    }, { passive: false });

문서 내부에 캔버스 태그 가있는 경우 캔버스 내부 개체의 사용성에 영향을 미칠 수 있습니다 (예 : 개체 이동). 따라서 아래 코드를 추가하여 수정하십시오.

    document.getElementById("canvasId").addEventListener("touchmove", function (e) {
        e.stopPropagation();
    }, { passive: false });

2

이 JS 솔루션을 사용해보십시오 :

var xStart, yStart = 0; 

document.addEventListener('touchstart', function(e) {
    xStart = e.touches[0].screenX;
    yStart = e.touches[0].screenY;
}); 

document.addEventListener('touchmove', function(e) {
    var xMovement = Math.abs(e.touches[0].screenX - xStart);
    var yMovement = Math.abs(e.touches[0].screenY - yStart);
    if((yMovement * 3) > xMovement) {
        e.preventDefault();
    }
});

터치 이벤트 리스너를 분리하지 않고 기본 Safari 스크롤 및 바운스 제스처를 방지합니다.


이렇게하면 웹 앱이 body 요소에서 완전히 스크롤되지 않습니다.
MartijnICU

2

어떤 솔루션도 나를 위해 작동하지 않습니다. 이것이 내가하는 방법이다.

  html,body {
      position: fixed;
      overflow: hidden;
    }
  .the_element_that_you_want_to_have_scrolling{
      -webkit-overflow-scrolling: touch;
  }

.the_element_that_you_want_to_have_scrolling {scrolling : touch; }
로이 Segall

귀하의 답변은 html, body에 대해 저에게 효과적이지만 스크롤하려면 "the_element_that_you_want_to_have_scrolling"을 얻을 수 없습니다. 이 요소는 본문 아래에있는 몇 개의 div 안에 중첩됩니다. 이 중첩 된 div에 대한 일반적인 요소 태그가 스크롤되도록하려는 것이 중요합니까? 나는 상대적인 위치가 있습니다.
ikwyl6


1

MyScript 웹 앱을 사용하고 실제로 글을 쓰는 대신 본문 스크롤 / 드래그 (iPad 및 태블릿에서)에 어려움을 겪고있는 사람들을 위해 :

<body touch-action="none" unresolved>

그것은 나를 위해 그것을 고쳤습니다.


1

스크롤 방지를 위해 js를 사용할 수 있습니다.

let body = document.body;

let hideScroll = function(e) {
  e.preventDefault();
};

function toggleScroll (bool) {

  if (bool === true) {
    body.addEventListener("touchmove", hideScroll);
  } else {
    body.removeEventListener("touchmove", hideScroll);
  }
}

그리고 toggleScroll모달을 조작 / 닫을 때 단순히 실행 / 중지하는 것보다 .

이렇게 toggleScroll(true) / toggleScroll(false)

(iOS 전용이며 Android에서는 작동하지 않음)


1

webkitOverflowScrolling스타일 을 전환하는이 JS 솔루션을 사용해보십시오 . 여기서 트릭은이 스타일이 꺼져 있고, 모바일 Safari가 일반 스크롤로 이동하고 오버 바운스를 방지한다는 것입니다. 아아, 진행중인 드래그를 취소 할 수 없습니다. 이 복잡한 솔루션은 또한 onscroll정상 위로 바운스 scrollTop가 추적 될 수있는 네거티브를 만드는 것으로 추적합니다. 이 솔루션은 iOS 12.1.1에서 테스트되었으며 단일 단점이 있습니다. 스크롤 속도를 높이는 동안 스타일을 재설정하면 즉시 취소되지 않을 수 있으므로 단일 오버 바운스가 여전히 발생합니다.

function preventScrollVerticalBounceEffect(container) {
  setTouchScroll(true) //!: enable before the first scroll attempt

  container.addEventListener("touchstart", onTouchStart)
  container.addEventListener("touchmove", onTouch, { passive: false })
  container.addEventListener("touchend", onTouchEnd)
  container.addEventListener("scroll", onScroll)

  function isTouchScroll() {
    return !!container.style.webkitOverflowScrolling
  }

  let prevScrollTop = 0, prevTouchY, opid = 0

  function setTouchScroll(on) {
    container.style.webkitOverflowScrolling = on ? "touch" : null

    //Hint: auto-enabling after a small pause makes the start
    // smoothly accelerated as required. After the pause the
    // scroll position is settled, and there is no delta to
    // make over-bounce by dragging the finger. But still,
    // accelerated content makes short single over-bounce
    // as acceleration may not be off instantly.

    const xopid = ++opid
    !on && setTimeout(() => (xopid === opid) && setTouchScroll(true), 250)

    if(!on && container.scrollTop < 16)
      container.scrollTop = 0
    prevScrollTop = container.scrollTop
  }

  function isBounceOverTop() {
    const dY = container.scrollTop - prevScrollTop
    return dY < 0 && container.scrollTop < 16
  }

  function isBounceOverBottom(touchY) {
    const dY = touchY - prevTouchY

    //Hint: trying to bounce over the bottom, the finger moves
    // up the screen, thus Y becomes smaller. We prevent this.

    return dY < 0 && container.scrollHeight - 16 <=
      container.scrollTop + container.offsetHeight
  }

  function onTouchStart(e) {
    prevTouchY = e.touches[0].pageY
  }

  function onTouch(e) {
    const touchY = e.touches[0].pageY

    if(isBounceOverBottom(touchY)) {
      if(isTouchScroll())
        setTouchScroll(false)
      e.preventDefault()
    }

    prevTouchY = touchY
  }

  function onTouchEnd() {
    prevTouchY = undefined
  }

  function onScroll() {
    if(isTouchScroll() && isBounceOverTop()) {
      setTouchScroll(false)
    }
  }
}

1

@Ben Bos 답변 개선 및 @Tim 댓글

이 CSS는 위치가 변경되거나 너비와 높이없이 약간 지연되기 때문에 CSS 다시 렌더링으로 스크롤 및 성능 문제를 방지하는 데 도움이됩니다.

body,
html {
  position: fixed;
  width: 100%; 
  height: 100%
}


IOS13에서이 나를 위해 깨끗한 솔루션이며, 아직 단점을 찾을 수 없습니다 ...
Soylent 그레이엄

0

바운스 현상을 없애고 싶지 않고 멈출 때만 알고 싶은 분들을 위해 (예 : 화면 거리 계산을 시작하기 위해) 다음을 수행 할 수 있습니다 (컨테이너는 넘쳐나는 컨테이너 요소입니다).

    const isBouncing = this.container.scrollTop < 0 ||
    this.container.scrollTop + this.container.offsetHeight >
        this.container.scrollHeight


-1

화가 키위와 비슷하게 위치보다는 높이를 사용하여 작업했습니다.

html,body {
  height: 100%;
  overflow: hidden;
}

.the_element_that_you_want_to_have_scrolling{
  -webkit-overflow-scrolling: touch;
}

문서로 이것은 모멘텀이 비활성화되지 않은 후에도 바운스를 활성화합니다
CaSUaL

@CaSUaL 무슨 뜻인지 잘 모르시겠습니까? 이 솔루션은 내 사용 사례에 적합했습니다 ...
austinh7

-1

테스트 된 솔루션, iOS 12.x에서 작동

이것은 내가 만난 문제입니다.

<body> <!-- the whole body can be scroll vertically -->
  <article>

    <my_gallery> <!-- some picture gallery, can be scroll horizontally -->
    </my_gallery>

  </article>
</body>

갤러리를 스크롤하는 동안 본문은 항상 자체 스크롤 (인간 스 와이프가 실제로 수평이 아님)하여 갤러리를 쓸모 없게 만듭니다.

내 갤러리가 스크롤을 시작하는 동안 내가 한 작업은 다음과 같습니다.

var html=jQuery('html');
html.css('overflow-y', 'hidden');
//above code works on mobile Chrome/Edge/Firefox
document.ontouchmove=function(e){e.preventDefault();} //Add this only for mobile Safari

그리고 내 갤러리가 스크롤을 끝내면 ...

var html=jQuery('html');
html.css('overflow-y', 'scroll');
document.ontouchmove=function(e){return true;}

도움이 되었기를 바랍니다 ~

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.