[Front-end Dictionary] Решение проблемы проникновения прокрутки

внешний интерфейс JavaScript

задний план

Продукт имеет три сокровища, всплывающее окно, плавающий слой и руководство;
У дизайна есть три сокровища: прозрачность, тень и закругленные углы;
В работе три сокровища, смс, пуш и красные конверты;
У программистов есть сокровище, и это невозможно сделать.

По мере увеличения доли мобильного рынка спрос становится более разнообразным. Сегодня мы обсуждаем проблему проникновения прокрутки на мобильную сторону. Приведенную выше шутку можно увидеть в требованиивсплывающее окноЭто все еще довольно распространено, так что это ипрокатное проникновениеКакая связь?

Позвольте мне объяснить, что такоепрокатное проникновение:

Страница выскальзывает из всплывающего окна. Когда мы коснемся экрана пальцами и проведем пальцем, мы обнаружим, что содержимое под всплывающим окном все еще прокручивается. Это явлениепрокатное проникновение.

Далее я расскажу о процессе моего исследования решения проблемы скользящего проникновения, надеясь вдохновить всех.

нужно

Требование: надеюсь, что при клике на картинку снизу выскочит полноэкранное всплывающее окно с описанием деталей этой картинки.

строить планы

Когда я получил это требование, я почувствовал, что это не сложно, поэтому я быстро выдвинул тест, а затем начал посещать Наггетс. Но когда я с удовольствием читал статьи больших парней, тест был на WeChat. Думаете об ошибке?

这是一张聊天截图
Я вдруг понял, что забыл разобраться с вопросом проникновения прокрутки при написании всплывающего окна. Помню, когда впервые столкнулся с этой проблемой, долго искал информацию.

Вариант первый:

Первый найденный метод - когда всплывающее окно запускается, дайтеoverflow: scroll:элементы плюсclass(как правилоbodyэлемент). убери это при выходеclass. Для удобства будет использоваться непосредственно следующееbodyelement для ссылки на элемент под всплывающим окном.

// css 部分
modal_open {
    position: fixed;
    height: 100%;
}

// js 部分
document.body.classList.add('modal_open');
document.body.classList.remove('modal_open');

Вышеупомянутый метод может решить проблему проникновения прокатки, но он также принесет новые проблемы.
который:

bodyПоложение прокрутки будет потеряно, т.е.bodyизscrollTopЗначение свойства становится равным 0.

Эта новая проблема более распространена, чем прокатиться через себя, поэтому эта программа предназначена для оптимизации.

Вариант 2:

С момента добавленияmodal_openэтоclassсделаюbodyПозиция прокрутки будет потеряна, так почему бы нам не сохранить позицию прокрутки до того, как она будет потеряна, и не установить сохраненную позицию прокрутки обратно перед выходом из всплывающего окна. Затем начните кодировать в этом направлении.

// css 部分
.modal_open {
  position: fixed;
  height: 100%;
}

// js 部分
/**
 * ModalHelper helpers resolve the modal scrolling issue on mobile devices
 * https://github.com/twbs/bootstrap/issues/15852
 */
var ModalHelper = (function(bodyClass) {
    var scrollTop;
    return {
        afterOpen: function() {
            scrollTop = document.scrollingElement.scrollTop  ||
                        document.documentElement.scrollTop || 
                        document.body.scrollTop;
            document.body.classList.add(bodyClass);
            document.body.style.top = -scrollTop + 'px';
        },
        beforeClose: function() {
            document.body.classList.remove(bodyClass);
            document.scrollingElement.scrollTop = document.documentElement.scrollTop = document.body.scrollTop = scrollTop;
        }
    };
})('modal_open');

// method
modalSwitch: function(){
    let self = this;
    if( self.switchFlag === 'close' ){
        ModalHelper.afterOpen();
        self.switchFlag = 'open';
    }else{
        ModalHelper.beforeClose();
        self.switchFlag = 'close';
    }
}

Вариант 2 позволяет добиться следующих эффектов:

  1. Когда всплывающее окно прокручивается, появляется следующееbodyфиксировано и не может быть прокручено;
  2. bodyПозиция прокрутки не теряется;
  3. bodyЕсть событие прокрутки;

Второе решение может адаптироваться к большинству потребностей всплывающих окон.После теста тестер не задавал никаких других вопросов.Эта проблема является идеальным решением. Но у меня есть вопрос в этом процессе:

Собственный эффект резинки IOS вызывает зависание страницы на короткое время.Причину этого я не нашел.Подскажите пожалуйста.

Другие варианты:

использоватьpreventDefaultБлокировать события браузера по умолчанию:

var modal = document.getElementById('modalBox');
modal.addEventListener('touchmove', function(e) {
    e.preventDefault();
}, false);

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

Используйте плагин:

Мое отношение к плагинам таково: если они не слишком сложны для самостоятельной реализации, лучше потратить время на их реализацию самостоятельно. Есть две причины:

  1. Использование плагина означает, что необходимо импортировать как минимум еще один файл.
  2. Слишком много плагинов, опасаюсь, что затраты на обслуживание обновления проекта в будущем увеличатся.

над.

Ссылаться на

  1. developer.Mozilla.org/en-US/docs/…
  2. Sky.com/2016-06/template…

Серия интерфейсных словарей

Серия «Front-end Dictionary» будет постоянно пополняться, и в каждом выпуске я буду рассказывать о точке знаний, которая появляется все чаще. Надеюсь, что в процессе прочтения в тексте будут неточности или ошибки, буду очень признательна, если что-то почерпну из этой серии, тоже буду очень рада.

Если вы считаете, что мои статьи написаны хорошо, то можете обратить внимание на мой паблик в WeChat, в котором заранее будут раскрыты спойлеры.

Вы также можете добавить мой WeChat wqhhsd, добро пожаловать в общение.

следующее уведомление

[Внешний словарь] Наследование — JavaScript должен понимать точки знаний

портал

  1. [Интерфейсный словарь] Она спросила меня, что такое «агент» сегодня.