ipad safari: відключити прокрутку та ефект відмов?


126

Я працюю над додатком на основі браузера, в даний час я розробляю і стилю для браузера ipad safari.

Я шукаю дві речі на ipad: Як я можу відключити вертикальну прокрутку для сторінок, які цього не потребують? & як я можу відключити ефект еластичного відмови?


зверніться до наступного відповіді тільки один , який працював для мене і є поточним ( stackoverflow.com/a/51176339/1979180 )
Frage

Відповіді:


157

Ця відповідь більше не застосовується, якщо ви не розробляєте для дуже старого пристрою iOS ... Перегляньте інші рішення


Відповідь 2011 року: Для веб-/ html-програми, що працює в iOS Safari, вам потрібно щось подібне

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

Для iOS 5 ви можете взяти до уваги наступне: document.ontouchmove та прокрутка на iOS 5

Оновлення вересня 2014 року: Більш ретельний підхід можна знайти тут: https://github.com/luster-io/prevent-overscroll . Про це та багато корисних порад щодо веб-сайту див. Http://www.luster.io/blog/9-29-14-mobile-web-checklist.html

Оновлення березня 2016 року: остання посилання більше не активна - див. 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)
Нілеш

7
А що з відключенням ефекту відмов ...?
Ювал А.

6
Проблема такого підходу полягає в тому, що прокручувані диви у вашому домі більше не прокручуються. Залежно від налаштування вашого будинку, існують способи цього.
huesforalice

3
Тут є багато людей, які запитують про прокручування дівів, використовуючи це так .. щоб зробити ці диви прокручуваними, додайте onTouchMove: function(e) { e.stopPropagation(); e.stopImmediatePropagation(); } Це запобіжить події потрапляння в тіло, але тіло залишатиметься непомітним. Редагувати: це припускаючи, що ви встановили $ ('div'). On ('touchmove', ... onTouchMove);
Метт Кенефік

1
@OskarAustegard Останнє посилання для мене не працювало, але я міг знайти вміст у веб-архіві: web.archive.org/web/20151103001838/http://www.luster.io/blog/…
falsarella

116

Ви також можете змінити положення тіла / html на фіксоване:

body,
html {
  position: fixed;
}

2
Це насправді дуже добре працювало на iPad iOS 8.2 Safari; більше ефекту відмов
Акселі Пален

3
Найкращий спосіб зробити це, що я бачив досі,
hildende

8
Не працює, якщо ви хочете розмістити щось з позиції: абсолютна і всі сторони встановлені на 0 (щоб зробити поділка на повноекранному екрані) - весь ваш документ скорочується ні до чого.
riv

4
Коли я використовую це, ця сторінка переходить на верхню частину сторінки, і тоді я зосереджуюсь на введенні. Чи знаєте ви спосіб цього?
Джулі

1
@riv додавання ширини: 100%; зріст: 100% як для тіла, так і для HTML допомогли мені.
Тім

58

Щоб уникнути прокрутки в сучасних мобільних браузерах, потрібно додати пасивне: 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
сер

2
Дякую вам за надання цього рішення!
Пол З.

6
Це правильна відповідь. Пояснення ви можете побачити тут: developer.mozilla.org/en-US/docs/Web/API/EventTarget/… після того, як Chrome 54 touchmove перейшов за замовчуванням у пасивне значення true, що означає ігнорувати виклики prevenDefault. Ось чому ви повинні пройти {passive: false}, тому виклик prevenDefault не ігнорується.
derickito

1
Ви декларуєте функцію в JS - Але як ви називаєте цю функцію на елементі, щоб вона працювала, як було запропоновано?
ikwyl6

4
Це чудово працює, якщо ви хочете відключити всі види прокрутки. Але що робити, якщо я хочу лише відключити прокрутку на тілі і зберегти можливість прокрутки елемента за допомогою overflow-y: scroll? Наприклад, маючи модаль з більшою висотою виду, ніж тіло.
Calsal

7

Ви можете використовувати цей фрагмент коду jQuery для цього:

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

Це заблокує вертикальне прокручування, а також будь-який ефект відскоку, який виникає на ваших сторінках.


11
Це не Javascript, це jQuery. Слід зазначити, що не всі використовують цю рамку.
інта

як я можу зупинити горизонтальний відскок або прокрутити
fidel castro

Горизонтальну прокрутку ви навіть можете відключити за допомогою css, застосувавши overflow-x: hidden; до вашого основного контейнера. Я помітив, що в останніх версіях сафарі ви не можете відключити ефект відмов. Це рідна особливість браузера на мобільних пристроях.
Алессандро Інкарнаті

6
@inta Просто кажу, що це насправді javascript. Це просто не чистий JavaScript.
Бен Лорантфі

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>, це все ще найкраще рішення. Однак при відкриванні клавіатури або ковзанні по екрану знизу вона більше не працюватиме.
Фабіан фон Еллертс

спробуйте
ввійти onfocus delete

4

Я знаю, що це злегка за піст, але я використовував Swiffy для перетворення Flash в інтерактивну гру HTML5 і натрапив на ту ж проблему прокрутки, але не знайшов жодного рішення, яке спрацювало б.

Проблема в мене полягала в тому, що етап Swiffy знімав весь екран, тому щойно він завантажився, подія touchmove документа ніколи не ініціювалась.

Якщо я спробував додати ту саму подію до контейнера Swiffy, це було замінено, як тільки етап завантажився.

Врешті-решт я вирішив це (досить безладно), застосувавши подію touchmove до кожного DIV в рамках сцени. Оскільки ці діви також постійно змінювалися, мені потрібно було постійно перевіряти їх.

Це було моє рішення, яке, здається, працює добре. Я сподіваюся, що це корисно для всіх, хто намагається знайти те саме рішення, що і я.

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

це вимикає весь прокрутку в ipad
fidel castro

3

Код для видалення ifari safari: вимкніть прокрутку та ефект відмов

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

Якщо у вас є тег полотна всередині документа, він колись вплине на зручність використання об'єкта всередині Canvas (приклад: переміщення об'єкта); тому додайте код нижче, щоб виправити його.

    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 за промовчанням і відмов жестів, не відриваючи слухачів сенсорних подій.


Це не дозволяє веб-додатку повністю прокручувати елемент тіла.
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; }
Рой Сегалл

Ваша відповідь працювала для мене на html, body, але я не можу отримати "the_element_that_you_want_to_have_scrolling" для прокрутки. Цей елемент вкладений всередині кількох дивів, які знаходяться під тілом. Чи має значення те, що будь-який з типових тегів елементів буде для цього вкладеного 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);
  }
}

І ніж просто запускати / зупиняти toggleScrollфункцію, коли ви опиняєте / закриваєте модальний.

Подобається це 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 допоможе запобігти прокрученню та виправленню продуктивності при повторному відтворенні 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


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

Сподіваюсь, це допомагає ~

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.