0

这是一个奇怪的!

概述:
我正在创建一个网络应用程序,并且创建了一个类似于您在 Facebook 应用程序中找到的菜单。向右滑动它会显示,向左滑动它会隐藏。

我通过将touchstart事件绑定到页面正文来做到这一点,此时我记录了手指按下的起点并绑定了touchmovetouchend事件。触摸移动事件找到当前手指位置并通过设置translate3d(x,y,z)以匹配手指位置来移动包含页面内容的 div 。

它实际上真的很棒。

touchend 上,我会计算手指是否移动到足以触发菜单显示或内容返回到其原始位置的程度。无论选择如何,我都会应用一个类,该类又将-webkit-transition: -webkit-transform 等应用于内容 div。然后,我再次使用translate3d(x,y,z)设置确定的结束位置,并设置一个变量来阻止任何进一步的敲击暂时停止工作。

这就是问题所在!

问题:
在这一点上,如果内容是简单的基本结构,即文章布局页面,那么过渡是快速和即时的。然而!如果内容很复杂,即一个大数据表,那么会有一个暂停,从 1 到 30 秒……非常令人沮丧。

当它最终起作用时,回调会解除与 body 的 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();

        }

    }
});

您将在上面看到使用的设置转换插件。

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

很抱歉发了这么长的帖子,这一直困扰着我很多!如果我无法解决问题,我将不得不把它撕掉。

我希望有人以前见过这个,并且可以提供帮助。(或者可以在上面的代码中看到一个明显的错误!)

谢谢,

将要 :)

4

1 回答 1

0

I solved this eventually, thought it may be useful to others!

Don't add any classes to the page, at all, between the end of the touchmove transition and the beginning of the transition that completes the movement.

My process used to be:

  1. On touchstart get finger x
  2. On touchmove position element based on current position and start position
  3. On touch end, decide whether to continue or reverse the animation based on distance moved.
  4. Add a class of close or open to the parent element that determines the final position.

However, adding this class forces safari to apply any style changes which is apparently quite intensive even if there are very few or even no changes. This is the reason for the pause.

I changed my process to apply the transition using javascript instead of adding classes and it is now silky smooth.

于 2012-04-27T14:54:06.857 回答