ipad Safari: ปิดการใช้งานการเลื่อนและเอฟเฟกต์การตีกลับ?


126

ฉันกำลังทำงานกับแอพที่ใช้เบราว์เซอร์ตอนนี้ฉันกำลังพัฒนาและจัดแต่งทรงผมสำหรับเบราว์เซอร์ซาฟารีของ ipad

ฉันกำลังมองหาสองสิ่งบน iPad: ฉันจะปิดการใช้งานการเลื่อนแนวตั้งสำหรับหน้าที่ไม่ต้องการได้อย่างไร & ฉันจะปิดใช้งานเอฟเฟกต์การตีกลับแบบยืดหยุ่นได้อย่างไร?


อ้างถึงคำตอบต่อไปนี้เท่านั้นที่เหมาะกับฉันและเป็นปัจจุบัน ( stackoverflow.com/a/51176339/1979180 )
frage

คำตอบ:


157

คำตอบนี้ใช้ไม่ได้อีกต่อไปเว้นแต่ว่าคุณกำลังพัฒนาสำหรับอุปกรณ์ iOS รุ่นเก่ามาก ... โปรดดูวิธีแก้ไขปัญหาอื่น ๆ


คำตอบปี 2011: สำหรับแอปพลิเคชันเว็บ / html ที่ทำงานใน iOS Safari ที่คุณต้องการ

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

สำหรับ iOS 5 คุณอาจต้องคำนึงถึงสิ่งต่อไปนี้: document.ontouchmove และ scrolling บน iOS 5

ปรับปรุงกันยายน 2014: วิธีการอย่างละเอียดมากขึ้นสามารถพบได้ที่นี่: https://github.com/luster-io/prevent-overscroll สำหรับคำแนะนำเกี่ยวกับเว็บแอปที่มีประโยชน์มากมายโปรดดูที่http://www.luster.io/blog/9-29-14-mobile-web-checklist.html

อัปเดตเดือนมีนาคม 2559: ลิงก์สุดท้ายนั้นไม่สามารถใช้งานได้อีกต่อไป - ดูhttps://web.archive.org/web/20151103001838/http://www.luster.io/blog/9-29-14-mobile-web-checklist .htmlสำหรับเวอร์ชันที่เก็บถาวรแทน ขอบคุณ @falsarella ที่ชี้ให้เห็น


1
ฉันมี webapp ที่ทำงานใน iOS Safari และฉันได้ลองปิดใช้งาน ontouchmove event แล้ว แต่ยังคงสามารถเห็นผลการตีกลับได้หากทำอย่างระมัดระวัง (iOS 5)
Nilesh

7
แล้วแค่ปิดการใช้งานเอฟเฟกต์ตีกลับ ... ?
Yuval A.

6
ปัญหาของวิธีนี้คือ div ที่เลื่อนได้ในโดเมนของคุณจะไม่เลื่อนอีกต่อไป ขึ้นอยู่กับการตั้งค่า Dom ของคุณมีหลายวิธีในการนี้
huesforalice

3
มีคนจำนวนมากที่นี่ถามเกี่ยวกับการเลื่อน div ในขณะที่ใช้สิ่งนี้ .. เพื่อให้ div เหล่านั้นเลื่อนได้ให้เพิ่มonTouchMove: function(e) { e.stopPropagation(); e.stopImmediatePropagation(); } มันจะป้องกันไม่ให้เหตุการณ์กระทบกับเนื้อหา แต่เนื้อหาจะยังคงไม่เด้ง แก้ไข: สมมติว่าคุณตั้งค่า $ ('div'). on ('touchmove', ... onTouchMove);
Matt Kenefick

1
@OskarAustegard ลิงก์สุดท้ายใช้ไม่ได้สำหรับฉัน แต่ฉันสามารถค้นหาเนื้อหาในที่เก็บถาวรของเว็บ: web.archive.org/web/20151103001838/http://www.luster.io/blog/…
falsarella

116

คุณยังสามารถเปลี่ยนตำแหน่งของ body / html เป็น fixed:

body,
html {
  position: fixed;
}

2
สิ่งนี้ทำงานได้ดีมากบน iPad iOS 8.2 Safari ไม่มีผลตีกลับอีกต่อไป
Akseli Palén

3
วิธีที่ดีที่สุดที่ฉันเคยเห็นมาจนถึงตอนนี้
hildende

8
ใช้งานไม่ได้ถ้าคุณต้องการวางบางอย่างด้วยตำแหน่ง: ค่าสัมบูรณ์และทุกด้านตั้งค่าเป็น 0 (เพื่อสร้าง div แบบเต็มหน้าจอ) - เอกสารทั้งหมดของคุณจะหดเหลือน้อยลง
riv

4
หน้าจะกระโดดกลับไปที่ด้านบนสุดของหน้าสำหรับฉันเมื่อฉันใช้สิ่งนี้จากนั้นฉันก็โฟกัสที่อินพุต คุณรู้วิธีแก้ปัญหานี้หรือไม่?
Julie

1
@riv เพิ่มความกว้าง: 100%; ความสูง: 100% ทั้งร่างกายและ html ช่วยฉัน
ทิม

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 ตั้งค่า passive เป็น true ซึ่งหมายความว่าการโทรป้องกันจะถูกละเว้น นั่นเป็นเหตุผลที่คุณต้องส่ง {passive: false} ดังนั้นการเรียก PreventDefault จึงไม่ถูกละเว้น
derickito

1
คุณกำลังประกาศฟังก์ชันใน JS - แต่คุณเรียกใช้ฟังก์ชันนี้ในองค์ประกอบอย่างไรจึงจะทำงานตามที่แนะนำได้
ikwyl6

4
ใช้งานได้ดีหากคุณต้องการปิดการใช้งานการเลื่อนทุกประเภท แต่จะเกิดอะไรขึ้นถ้าฉันต้องการปิดการใช้งานการเลื่อนบนร่างกายและรักษาความเป็นไปได้ในการเลื่อนองค์ประกอบด้วยoverflow-y: scroll? ตัวอย่างเช่นมีกิริยาที่มีมุมมองสูงกว่าร่างกาย
Calsal

7

คุณสามารถใช้ข้อมูลโค้ด jQuery นี้เพื่อทำสิ่งนี้:

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

การดำเนินการนี้จะบล็อกการเลื่อนในแนวตั้งและเอฟเฟกต์ตีกลับใด ๆ ที่เกิดขึ้นบนหน้าเว็บของคุณ


11
นี่ไม่ใช่ Javascript แต่เป็น jQuery คุณควรพูดถึงเรื่องนี้ไม่ใช่ทุกคนที่ใช้กรอบนั้น
inta

ฉันจะหยุดการเด้งหรือเลื่อนในแนวนอนได้อย่างไร
fidel castro

การเลื่อนแนวนอนคุณสามารถปิดการใช้งานได้ด้วย css โดยใช้ overflow-x: hidden; ไปยังคอนเทนเนอร์หลักของคุณ ฉันสังเกตเห็นใน Safari เวอร์ชันล่าสุดคุณไม่สามารถปิดใช้งานเอฟเฟกต์ตีกลับได้ เป็นคุณสมบัติดั้งเดิมของเบราว์เซอร์บนอุปกรณ์มือถือ
Alessandro Incarnati

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

ลองใส่
ออนโฟกัส

4

ฉันรู้ว่านี่เป็นเรื่องเล็กน้อย แต่ฉันใช้ Swiffy เพื่อแปลง Flash เป็นเกม HTML5 แบบโต้ตอบและพบปัญหาการเลื่อนแบบเดียวกัน แต่ไม่พบวิธีแก้ปัญหาที่ได้ผล

ปัญหาที่ฉันมีคือเวที Swiffy กำลังขึ้นทั้งหน้าจอดังนั้นทันทีที่โหลดขึ้นเหตุการณ์การสัมผัสของเอกสารจะไม่ถูกทริกเกอร์

หากฉันพยายามเพิ่มเหตุการณ์เดียวกันลงในคอนเทนเนอร์ Swiffy เหตุการณ์นั้นจะถูกแทนที่ทันทีที่เวทีโหลด

ในที่สุดฉันก็แก้ไขมัน (ค่อนข้างยุ่ง) โดยใช้เหตุการณ์ touchmove กับทุก DIV ภายในเวที เนื่องจาก div เหล่านี้มีการเปลี่ยนแปลงตลอดเวลาฉันจึงต้องตรวจสอบต่อไป

นี่เป็นวิธีแก้ปัญหาของฉันซึ่งดูเหมือนว่าจะได้ผลดี ฉันหวังว่าจะเป็นประโยชน์สำหรับใครก็ตามที่พยายามหาวิธีแก้ปัญหาเช่นเดียวกับฉัน

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

สิ่งนี้ปิดใช้งานการเลื่อนทั้งหมดใน ipad
fidel castro

3

Code to ในการลบ ipad safari: ปิดการใช้งานการเลื่อนและการตีกลับ

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

หากคุณมีแท็กcanvasอยู่ในเอกสารบางครั้งอาจมีผลต่อการใช้งานของวัตถุภายใน Canvas (ตัวอย่าง: การเคลื่อนที่ของวัตถุ) ดังนั้นเพิ่มโค้ดด้านล่างเพื่อแก้ไข

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

2

ลองใช้ JS Sollutuion :

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 ตามค่าเริ่มต้นโดยไม่ต้องถอดผู้ฟังเหตุการณ์สัมผัสของคุณ


สิ่งนี้จะหยุดไม่ให้เว็บแอปเลื่อนไปที่องค์ประกอบของร่างกาย
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; }
Roy Segall

คำตอบของคุณใช้ได้ผลสำหรับฉันสำหรับ html เนื้อหา แต่ฉันไม่สามารถเลื่อน "the_element_that_you_want_to_have_scrolling" ได้ องค์ประกอบนี้ซ้อนอยู่ภายใน div สองสามตัวที่อยู่ใต้ตัว มันสำคัญหรือไม่ว่าแท็กองค์ประกอบทั่วไปจะเป็นอย่างไรสำหรับ div ที่ซ้อนกันนี้ที่ฉันต้องการให้เลื่อน ฉันมีตำแหน่ง: ญาติ
ikwyl6

2

ทดสอบใน iphone เพียงใช้ css นี้บนคอนเทนเนอร์องค์ประกอบเป้าหมายและมันจะเปลี่ยนพฤติกรรมการเลื่อนซึ่งจะหยุดเมื่อนิ้วออกจากหน้าจอ

-webkit-overflow-scrolling: auto

https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-overflow-scrolling


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

และไม่ใช่แค่เรียกใช้ / หยุด toggleScrollfunc เมื่อคุณเปิด / ปิดโมดอล

แบบนี้ toggleScroll(true) / toggleScroll(false)

(สำหรับ iOS เท่านั้นบน Android ไม่ทำงาน)


1

ลองใช้โซลูชัน JS ที่สลับwebkitOverflowScrollingสไตล์ เคล็ดลับที่นี่คือสไตล์นี้ปิดอยู่ 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 นี้จะช่วยป้องกันปัญหาการเลื่อนและประสิทธิภาพในการ re-render css เนื่องจากตำแหน่งมีการเปลี่ยนแปลง / มีความล่าช้าเล็กน้อยโดยไม่มีความกว้างและความสูง

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


บน IOS13 นี่เป็นวิธีแก้ปัญหาที่สะอาดที่สุดสำหรับฉันและยังไม่พบข้อบกพร่องใด ๆ ...
Soylent Graham

0

สำหรับผู้ที่ไม่ต้องการกำจัดการตีกลับ แต่เพียงแค่รู้ว่าเมื่อใดที่มันหยุด (เช่นเริ่มคำนวณระยะทางหน้าจอ) คุณสามารถทำสิ่งต่อไปนี้ได้ (คอนเทนเนอร์คือองค์ประกอบของคอนเทนเนอร์ที่ล้น):

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

0

ปิดใช้งานเอฟเฟกต์การเลื่อนเด้งของซาฟารี:

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

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