iPhone / iPad 용 자바 스크립트 스크롤 이벤트?


107

iPad에서 스크롤 이벤트를 캡처 할 수없는 것 같습니다. 이 작업 중 어느 것도 내가 뭘 잘못하고 있습니까?

window.onscroll=myFunction;

document.onscroll=myFunction;

window.attachEvent("scroll",myFunction,false);

document.attachEvent("scroll",myFunction,false);

Windows의 Safari 3에서도 모두 작동합니다. 아이러니하게도 PC의 모든 브라우저는 window.onload=기존 이벤트를 방해하지 않아도 지원 합니다. 하지만 아이 패드는 사용하지 마십시오.

답변:


146

iPhoneOS는 onscroll예상 할 수있는 방식을 제외하고 이벤트를 캡처 합니다.

한 손가락 이동은 사용자가 이동을 중지 할 때까지 이벤트를 생성하지 않습니다 onscroll. 페이지가 이동을 중지하고 다시 그릴 때 이벤트가 생성됩니다 (그림 6-1 참조).

마찬가지로 두 손가락으로 스크롤하면 스크롤을 onscroll중지 한 후에 만 실행 됩니다.

처리기를 설치하는 일반적인 방법은 예를 들어 작동합니다.

window.addEventListener('scroll', function() { alert("Scrolled"); });
// or
$(window).scroll(function() { alert("Scrolled"); });
// or
window.onscroll = function() { alert("Scrolled"); };
// etc 

( https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html 참조 )


23
감사합니다. 이로 인해 문제를 더 자세히 살펴보아야했습니다. 진짜 대답은 아이폰 / 아이 패드의 뷰포트 상단이 존재하는 다른 모든 브라우저 / 하드웨어와 같이 작동 window.pageYOffset 하지 않고 작동하는 것을 감지하는 것이 었습니다 document.body.scrollTop||document.documentElement.scrollTop.
ck_

6
@ck_ IPAD의 Unfortunatelly window.pageYOffset는 감속 단계에서 업데이트되지 않지만 스크롤이 완료 될 때만 업데이트됩니다.
Adaptabi

2
window.onscroll을 직접 덮어 쓰는 것은 좋지 않습니다. 이벤트 리스너를 추가하는 것이 더 좋습니다. window.addEventListener ( 'scroll', function () {alert ( 'scrolled!');}); 사용
Kevin Dice

4
ehm .. 실제로 window.onscroll은 패닝 중, 패닝 후 감속하는 동안 항상 내 ipad에서 실행됩니다. 뭔가 바뀌 었나요?
commonpike

Safari (및 기타)는 iOS 8에서 WKWebView를 사용하도록 변경되었습니다. Chrome 및 Cordova는 여전히 UIWebView를 사용하므로 연속 스크롤 이벤트가 발행되지 않는 문제가 계속 나타납니다. 하지만 Cordova 용 WKWebView 플러그인이 있습니다.
jiku

105

iOS의 경우 다음 과 같은 스크롤 이벤트와 함께 touchmove 이벤트 를 사용해야합니다 .

document.addEventListener("touchmove", ScrollStart, false);
document.addEventListener("scroll", Scroll, false);

function ScrollStart() {
    //start of scroll event for iOS
}

function Scroll() {
    //end of scroll event for iOS
    //and
    //start/end of scroll event for other browsers
}

37
이 이벤트는 사용자가 적극적으로 스크롤 할 때만 발생하며 운동량 스크롤의 감속 단계에서는 발생하지 않습니다.
Jon Tirsen 2012 년

내가 iOS 용 최종 스크롤 감지 코드를 포함하는 코드를 변경
조지 Filippakos

데스크탑에서 스크롤하는 것과 유사하게 작동하는 "touchend"에 대한 리스너를 추가 할 수도 있습니다.
BingeBoy

1
이 스크롤 단계에서 액세스 제공하지 않습니다
벤 Sewards

3
3 년이 지났습니다. 감속 중에 스크롤 위치를 실시간으로 업데이트 할 수 없습니다. 지도 같은 앱을 어떻게 작성해야하나요 ?????
FlavorScape

38

이전 게시물에 다른 답변을 추가하여 죄송하지만 일반적 으로이 코드를 사용하여 스크롤 이벤트를 매우 잘 얻습니다 (최소 6.1에서 작동합니다)

element.addEventListener('scroll', function() {
    console.log(this.scrollTop);
});

// This is the magic, this gives me "live" scroll events
element.addEventListener('gesturechange', function() {});

그리고 그것은 나를 위해 작동합니다. 하지 않는 유일한 일은 스크롤의 감속에 대한 스크롤 이벤트를 제공하는 것입니다 (감속이 완료되면 최종 스크롤 이벤트가 발생하고 원하는대로 수행합니다).하지만 이렇게하여 CSS로 관성을 비활성화하면

-webkit-overflow-scrolling: none;

당신은 당신의 요소에 관성을 얻지 않습니다.

document.addEventListener('touchmove', function(e) {e.preventDefault();}, true);

7
유효한 답변에 반대표를 던지고 문제를 설명하는 댓글을 남기지 않는 이유는 무엇입니까?
Dave Mackintosh 2014 년

3
반대 투표가 쉽고 빠르기 때문입니다. : /
Zeshan Ahmed

5
저자에 따르면 대답은 항상 "유효"입니다 ... 아무도 고의로 잘못된 대답을 게시하지 않습니다. 그러나 예, 그들은 왜 반대표를 던 졌는지 설명 했어야했습니다.
Matthieu Charbonnier

3
gesturechange이벤트는 표준이
아니며

6

iScroll을 사용하여이 문제에 대한 훌륭한 솔루션을 얻을 수있었습니다. 모멘텀 스크롤링과 모든 것 https://github.com/cubiq/iscroll github doc은 훌륭했고 저는 대부분 그것을 따랐습니다. 내 구현에 대한 세부 정보는 다음과 같습니다.

HTML : iScroll에서 사용할 수있는 일부 div에서 콘텐츠의 스크롤 가능 영역을 래핑했습니다.

<div id="wrapper">
  <div id="scroller">
    ... my scrollable content
  </div>
</div>

CSS : "터치"에 대한 Modernizr 클래스를 사용하여 스타일 변경 사항을 터치 장치에만 적용했습니다 (터치 할 때만 iScroll을 인스턴스화했기 때문).

.touch #wrapper {
  position: absolute;
  z-index: 1;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  overflow: hidden;
}
.touch #scroller {
  position: absolute;
  z-index: 1;
  width: 100%;
}

JS : iScroll 다운로드에서 iscroll-probe.js를 포함시킨 다음 아래와 같이 스크롤러를 초기화했습니다. 여기서 updatePosition은 새 스크롤 위치에 반응하는 내 함수입니다.

# coffeescript
if Modernizr.touch
  myScroller = new IScroll('#wrapper', probeType: 3)
  myScroller.on 'scroll', updatePosition
  myScroller.on 'scrollEnd', updatePosition

스크롤 오프셋을 보는 대신 myScroller를 사용하여 현재 위치를 가져와야합니다. 다음은 http://markdalgleish.com/presentations/embracingtouch/ 에서 가져온 기능입니다 (매우 유용한 기사이지만 지금은 약간 구식 임).

function getScroll(elem, iscroll) {   
  var x, y;

  if (Modernizr.touch && iscroll) {
    x = iscroll.x * -1;
    y = iscroll.y * -1;   
  } else {
    x = elem.scrollTop;
    y = elem.scrollLeft;   
  }

  return {x: x, y: y}; 
}

유일한 다른 문제는 가끔 스크롤하려는 페이지의 일부를 잃어 버리고 스크롤을 거부한다는 것입니다. #wrapper의 내용을 변경할 때마다 myScroller.refresh ()에 대한 일부 호출을 추가해야했고 문제가 해결되었습니다.

편집 : 또 다른 문제는 iScroll이 모든 "클릭"이벤트를 먹는다는 것입니다. iScroll에서 "탭"이벤트를 내보내고 "클릭"이벤트 대신 처리하도록 옵션을 설정했습니다. 고맙게도 스크롤 영역을 많이 클릭 할 필요가 없었기 때문에 큰 문제가 아니 었습니다.


1

iOS 8이 나왔기 때문에이 문제는 더 이상 존재하지 않습니다. 스크롤 이벤트는 이제 iOS Safari에서도 원활하게 시작됩니다.

따라서 scroll이벤트 핸들러 를 등록하고 해당 이벤트 핸들러 window.pageYOffset내부를 확인 하면 모든 것이 잘 작동합니다.


1
Cordova 사용과 같은 일부 사용 사례에는 아직 존재합니다. developer.telerik.com/featured/…
diosney

6
내 경험이 여전히 2019 년 현재 iOS 장비에 문제가 남아있다
크리스
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.