Ipad Safari: отключить прокрутку и эффект отказов? - PullRequest
112 голосов
/ 14 октября 2011

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

Я ищу две вещи на iPad: как отключить вертикальную прокрутку для страниц, которые не требуют этого? & как отключить эффект упругого отскока?

Ответы [ 15 ]

153 голосов
/ 14 октября 2011

Этот ответ больше не применим, если вы не разрабатываете для очень старого устройства 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 за указание на это.

96 голосов
/ 14 апреля 2015

Вы также можете изменить положение тела / html на фиксированное:

body,
html {
  position: fixed;
}
34 голосов
/ 16 апреля 2018

Чтобы предотвратить прокрутку в современных мобильных браузерах, необходимо добавить пассив: false.Я выдергивал свои волосы, заставляя это работать, пока я не нашел это решение.Я нашел это упомянутое в другом месте в Интернете.

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

function disableScroll(){
    document.body.addEventListener('touchmove', preventDefault, { passive: false });
}
function enableScroll(){
    document.body.removeEventListener('touchmove', preventDefault);
}
7 голосов
/ 26 ноября 2013

Вы можете использовать этот фрагмент кода jQuery для этого:

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

Это заблокирует вертикальную прокрутку, а также любой эффект отскока, возникающий на ваших страницах.

4 голосов
/ 20 марта 2015
overflow: scroll;
-webkit-overflow-scrolling: touch;

В контейнере вы можете установить эффект отскока внутри элемента

Источник: http://www.kylejlarson.com/blog/2011/fixed-elements-and-scrolling-divs-in-ios-5/

4 голосов
/ 25 марта 2014

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

Проблема, с которой я столкнулся, заключалась в том, что этап Swiffy занимал весь экран, поэтому, как только он загрузился, событие touchmove документа никогда не запускалось.

Если я попытался добавить то же событие в контейнер Swiffy, оно было заменено сразу после загрузки сцены.

В конце концов, я решил это (довольно беспорядочно), применив событие touchmove к каждому DIV на сцене. Поскольку эти div тоже постоянно менялись, мне нужно было их проверять.

Это было мое решение, которое, кажется, работает хорошо. Я надеюсь, что это будет полезно для всех, кто пытается найти то же решение, что и я.

var divInterval = setInterval(updateDivs,50);
function updateDivs(){
$("#swiffycontainer > div").bind(
    'touchmove',
     function(e) {
        e.preventDefault();
    }
);}
2 голосов
/ 13 октября 2017

Проверено в iphone.Просто используйте эту CSS на контейнере целевого элемента, и он изменит поведение прокрутки, которое останавливается, когда палец покидает экран.

-webkit-overflow-scrolling: auto

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

2 голосов
/ 05 февраля 2017

ни одно из решений не работает для меня. Вот как я это делаю.

  html,body {
      position: fixed;
      overflow: hidden;
    }
  .the_element_that_you_want_to_have_scrolling{
      -webkit-overflow-scrolling: touch;
  }
2 голосов
/ 04 сентября 2015

Попробуйте это решение 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 по умолчанию без отсоединения слушателей сенсорных событий.

1 голос
/ 15 января 2019

Попробуйте это решение 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)
    }
  }
}
...