Как я могу остановить мобильный Safari от приостановки перед началом перехода - PullRequest
0 голосов
/ 24 февраля 2012

это странно!

Обзор:
Я создаю веб-приложение и создал меню, похожее на то, которое вы найдете в приложении Facebook. Проведите пальцем вправо, и он покажет, налево, и он прячется.

Я делаю это, привязывая событие touchstart к телу страницы, в этот момент я записываю начальную точку нажатия пальцем, а также привязываю touchmove и touchend событие. Событие сенсорного перемещения находит текущую позицию пальца и перемещает div, содержащий содержимое страницы, устанавливая translate3d (x, y, z) в соответствии с позицией пальца.

Это на самом деле работает очень хорошо.

Вкл. touchend Затем я выясняю, переместился ли палец достаточно далеко, чтобы вызвать отображение меню или возврат содержимого в исходное положение. Независимо от выбора я применяю класс, который в свою очередь применяет -webkit-transition: -webkit-transform и т. Д. к содержимому div. Затем я устанавливаю определенную конечную позицию, снова используя translate3d (x, y, z) , а также устанавливаю переменную, которая останавливает любые последующие отводы от временной работы.

И здесь возникает проблема!

Проблема:
На этом этапе, если контент простой с базовой структурой, то есть страницей макета статьи, переход происходит быстро и мгновенно. Тем не мение! Если содержание сложное, то есть большая таблица данных, тогда возникает пауза, от 1 до 30 секунд ... Очень расстраивает.

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

Я тестирую на iPad 1. Кажется, что нет никакой корреляции между скоростью пролистывания и продолжительностью паузы. Кроме того, между расстоянием, оставшимся для перемещения контента, нет.

Наконец, и я думаю, что это ключ!
Есть кнопка, которая выполняет то же действие открытия и закрытия автоматически (опять же, как в Facebook), которая работает нормально, и если вы проводите пальцем по экрану, она останавливается, а затем вы нажимаете на эту кнопку, она мгновенно начинает работать, хотя и в неправильном направлении, когда переключается на основе. на переменную, которая уже была установлена ​​для открытия. Это почти как если бы она очищала какую-то очередь анимации и разбиралась сама с собой ...

Какой-то код:
JavaScript

$body.bind({
    'touchstart': function(e){

        if( !swipeBan ){

            // Reset
            var used = false,
                triggered = false,
                dir = false;

            // Get start point
            start.x = e.originalEvent.touches[0].pageX;
            start.y = e.originalEvent.touches[0].pageY;

            $body.bind({
                'touchmove':    function(e){

                    // Get current value (will be the end value too)
                    end.x = e.originalEvent.touches[0].pageX;
                    end.y = e.originalEvent.touches[0].pageY;

                    // If we have not chosen a direction, choose one
                    if( !dir ){

                        dir = getDir();

                    }else{

                        var left = open && dir == 'left',
                            right = !open && dir == 'right';

                        if( left || right ){

                            var x = left ? maxSwipe - getDist('left') : getDist('right');

                            $content.setTransform(x);

                            used = true;
                            triggered = left ? maxSwipe - x > swipeTrigger : x > swipeTrigger;

                            e.preventDefault();

                        }

                    }

                },
                'touchend': function(e){

                    // Only go further if we are going the correct direction
                    if( used ){

                        swipeBan = true;

                        // Get ready for animation
                        function done(){

                            // Get touching!
                            swipeBan = false;

                            // Stop animating
                            $content.removeClass('animate');

                        }

                        // Add animate class
                        $content.addClass('animate');

                        // Set the value
                        if( ( !open && triggered ) || ( open && !triggered ) ){

                            $content.setTransform(maxSwipe,0,function(){
                                done();
                            });

                            $body.removeClass('closed');

                            open = true;

                        }else if( ( !open && !triggered ) || ( open && triggered ) ){

                            $content.setTransform(0,0,function(){
                                done();
                            });

                            $body.addClass('closed');

                            open = false;

                        }

                    }

                    // Unbind everything
                    $body.unbind('touchmove touchend');

                }
            });

        }else{

            e.preventDefault();

        }

    }
});

Плагин set transform, который вы увидите, использованный выше.

$.fn.setTransform = function(x,y,callback){

    y = y ? y : '0';

    var $this = $(this);

    if( callback ){

        $this.one('webkitTransitionEnd',function(){

             callback.apply(this);

        });

    }

    $this.css({
        '-webkit-transform':    'translate3d(' + x + 'px,' + y + '%,0)'
    });

    return this;

}

CSS, очень просто. Существуют и другие стили, но они чисто визуальные:

#content.animate {
    -webkit-transition: -webkit-transform .3s cubic-bezier(.16,0,0,1);
}

Извините за длинный пост, это меня очень беспокоило! В тот момент, когда я не смогу разобрать проблему, мне придется ее разорвать.

Я надеюсь, что кто-то видел это раньше и может помочь. (Или вы можете увидеть очевидную ошибку в приведенном выше коде!)

Спасибо

Будет:)

1 Ответ

0 голосов
/ 27 апреля 2012

Я решил это в конце концов, подумал, что это может быть полезно для других!

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

Мой процесс был:

  1. На сенсорном старте получить палец х
  2. На элементе положения сенсорного перемещения, основанный на текущей позиции и начале положение
  3. При касании решите, продолжать ли анимацию или повернуть ее вспять. в зависимости от пройденного расстояния.
  4. Добавить класс close или open к родительскому элементу, который определяет конечная позиция.

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

Я изменил свой процесс, чтобы применить переход, используя javascript вместо добавления классов, и теперь он шелковисто гладкий.

...