javascript เลื่อนเหตุการณ์สำหรับ iPhone / iPad?


107

ฉันไม่สามารถจับภาพเหตุการณ์การเลื่อนบน iPad ได้ ไม่มีงานเหล่านี้ฉันทำอะไรผิด?

window.onscroll=myFunction;

document.onscroll=myFunction;

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

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

ทั้งหมดนี้ทำงานได้แม้กระทั่งบน Safari 3 บน Windows แดกดันทุกเบราว์เซอร์บนพีซีรองรับwindow.onload=หากคุณไม่รังเกียจที่จะปิดบังเหตุการณ์ที่มีอยู่ แต่ไม่ไปบน iPad

คำตอบ:


147

iPhoneOS จะจับภาพonscrollเหตุการณ์ยกเว้นไม่ใช่อย่างที่คุณคาดหวัง

การแพนเพียงนิ้วเดียวจะไม่สร้างเหตุการณ์ใด ๆ จนกว่าผู้ใช้จะหยุดการแพน - onscrollเหตุการณ์จะถูกสร้างขึ้นเมื่อหน้าหยุดเคลื่อนไหวและวาดใหม่ดังแสดงในรูปที่ 6-1

ในทำนองเดียวกันการเลื่อนด้วย 2 นิ้ว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
ขอบคุณที่บังคับให้ฉันต้องพิจารณาปัญหาเพิ่มเติม คำตอบที่แท้จริงคือการตรวจพบส่วนบนสุดของวิวพอร์ตบน iPhone / iPad เท่านั้นที่ใช้งาน window.pageYOffset ได้และไม่ document.body.scrollTop||document.documentElement.scrollTop เหมือนกับเบราว์เซอร์ / ฮาร์ดแวร์อื่น ๆ ที่มีอยู่
ck_

6
@ck_ Unfortunatelly บน IPAD window.pageYOffsetไม่ได้รับการอัปเดตในระยะชะลอตัว แต่เมื่อเลื่อนเสร็จสิ้นเท่านั้น
Adaptabi

2
การเขียนทับ window.onscroll โดยตรงเป็นการปฏิบัติที่ไม่ดี การเพิ่มผู้ฟังเหตุการณ์จะดีกว่า ใช้ window.addEventListener ('scroll', function () {alert ('scrolled!');});
Kevin Dice

4
อืม .. อันที่จริง window.onscroll กำลังทำงานบน iPad ของฉันตลอดเวลาในขณะนี้ในขณะที่แพนกล้องและหลังจากการแพนขณะที่ชะลอตัวลง มีอะไรเปลี่ยนแปลงไหม
commonpike

Safari (และอาจจะอื่น ๆ ) เปลี่ยนไปใช้ WKWebView กับ iOS 8 Chrome และ Cordova ยังคงใช้ UIWebView ดังนั้นจึงยังคงแสดงปัญหาเกี่ยวกับเหตุการณ์การเลื่อนอย่างต่อเนื่องที่ไม่มีการออก แม้ว่าจะมีปลั๊กอิน WKWebView สำหรับ Cordova
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

ฉันเปลี่ยนรหัสเพื่อรวมรหัสตรวจจับการเลื่อนท้ายสำหรับ iOS
George Filippakos

คุณอาจต้องการเพิ่ม Listener สำหรับ "สัมผัส" ซึ่งจะทำหน้าที่คล้ายกับการเลื่อนบนเดสก์ท็อป
BingeBoy

1
โปรดทราบว่าสิ่งนี้ไม่ได้ให้การเข้าถึงระหว่างขั้นตอนการเลื่อน
Ben Sewards

3
เป็นเวลาสามปีแล้ว ฉันไม่สามารถรับการอัปเดตตำแหน่งการเลื่อนแบบเรียลไทม์ระหว่างการชะลอตัว ฉันจะเขียนแอพที่เหมือนแผนที่ได้อย่างไร ?????
FlavourScape

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

3
เนื่องจากการลงคะแนนทำได้ง่ายและรวดเร็ว : /
Zeshan Ahmed

5
คำตอบคือ "ถูกต้อง" ตามผู้เขียนเสมอ ... ไม่มีใครโพสต์คำตอบที่ไม่ถูกต้องโดยเจตนา แต่ใช่พวกเขาควรจะอธิบายได้ว่าทำไมพวกเขาจึงลดคะแนนลง
Matthieu Charbonnier

3
gesturechangeเหตุการณ์ไม่ได้มาตรฐานและรองรับโดย Safari เท่านั้น: developer.mozilla.org/en-US/docs/Web/Events/gesturechange
Nicolas Bouvrette

6

ฉันสามารถหาทางออกที่ยอดเยี่ยมสำหรับปัญหานี้ด้วย iScroll ด้วยความรู้สึกของการเลื่อนโมเมนตัมและทุกอย่างhttps://github.com/cubiq/iscrollเอกสาร github นั้นยอดเยี่ยมมากและฉันก็ติดตามมันเป็นส่วนใหญ่ นี่คือรายละเอียดการใช้งานของฉัน

HTML: ฉันรวมพื้นที่ที่เลื่อนได้ของเนื้อหาของฉันใน div บางตัวที่ iScroll สามารถใช้ได้:

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

CSS: ฉันใช้คลาส Modernizr สำหรับ "touch" เพื่อกำหนดเป้าหมายการเปลี่ยนแปลงสไตล์ของฉันกับอุปกรณ์สัมผัสเท่านั้น (เพราะฉันสร้างอินสแตนซ์ 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-probe.js จากการดาวน์โหลด iScroll จากนั้นเริ่มต้น scroller ดังต่อไปนี้โดยที่ 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}; 
}

gotcha อื่น ๆ เท่านั้นที่บางครั้งฉันจะสูญเสียส่วนหนึ่งของหน้าเว็บที่ฉันพยายามจะเลื่อนไปและมันจะปฏิเสธที่จะเลื่อน ฉันต้องเพิ่มการโทรไปยัง myScroller.refresh () เมื่อใดก็ตามที่ฉันเปลี่ยนเนื้อหาของ #wrapper และนั่นช่วยแก้ปัญหาได้

แก้ไข: gotcha อีกอย่างคือ iScroll กินเหตุการณ์ "คลิก" ทั้งหมด ฉันเปิดตัวเลือกให้ iScroll ปล่อยเหตุการณ์ "แตะ" และจัดการเหตุการณ์เหล่านั้นแทนการ "คลิก" เหตุการณ์ โชคดีที่ฉันไม่ต้องการการคลิกในพื้นที่เลื่อนมากนักดังนั้นนี่จึงไม่ใช่เรื่องใหญ่


1

ตั้งแต่ iOS 8 ออกมาปัญหานี้ก็ไม่มีอีกต่อไป ตอนนี้เหตุการณ์การเลื่อนจะเริ่มอย่างราบรื่นใน iOS Safari เช่นกัน

ดังนั้นหากคุณลงทะเบียนscrollตัวจัดการเหตุการณ์และตรวจสอบwindow.pageYOffsetภายในตัวจัดการเหตุการณ์นั้นทุกอย่างก็ใช้ได้ดี


1
ยังมีอยู่ในบางกรณีการใช้งานเช่นการใช้ Cordova developer.telerik.com/featured/…
diosney

6
ประสบการณ์ของฉันคือปัญหานี้ยังคงเป็นปัญหากับอุปกรณ์ iOS ปัจจุบันในปี 2019
คริส
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.