在页面转换完成时暂停 Meteor 的 Iron Router 中的路由

Posted

技术标签:

【中文标题】在页面转换完成时暂停 Meteor 的 Iron Router 中的路由【英文标题】:Pause routing in Meteor's Iron Router while a page transition completes 【发布时间】:2014-09-14 22:12:09 【问题描述】:

在我的 Meteor 应用程序中,我有一些复杂的页面动画,需要几秒钟才能完成(指导性动画优先于页面转换速度)。

动画中有一个out 状态和一个in 状态。为简单起见,假设我需要淡出一页,然后淡入下一页,但我希望这些淡出需要几秒钟。为此,我使用 Meteor 的 Iron Router 来调用一些操纵 CSS 的动画函数。

lib/router.js

animateContentOut = function(pause) 
    return $('#content').removeClass("animated fadeIn");

Router.onAfterAction(animateContentOut);

animateContentIn = function() 
    return $('#content').addClass("animated fadeIn");

Router.onAfterAction(animateContentIn);

这是基于Manuel Schoebel 的一个很好的提示,并且fadeIn 有效。但是,我的淡入淡出动画需要几秒钟。所以用户只能看到淡出动画的前几毫秒,因为它开始了,然后路由器在动画完成之前快速导航到新路由。

所以我的问题是:我如何告诉路由器等待动画完成或 onAfterAction 调用中的某个动作的 setTimeout?为离开页面的过程制作动画时是否有更好的钩子?

【问题讨论】:

您可能希望在github.com/percolatestudio/iron-transitioner 中查看github.com/tmeasday/iron-transitioner 及其当前分支。 我研究了过渡器上的不同分支,但我不知道如何使它与我的视图/模板结构一起工作。似乎我无法在不同视图之间进行转换。但是,我可能看的不够近。 【参考方案1】:

这取决于产生页面变化的原因。如果它是一个链接/按钮/通用事件,那么您可以只注册一个如下所示的事件,而不是使用锚href,并将您想要移动到的路线(如“/home”)存储在data-route 属性中锚标记:

Template.links.events(
    'click a': function(event) 
        var _currentTarget = event.currentTarget;
        $('#content').removeClass('animated fadeIn').on('transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd', function() 
            Router.current().redirect(_currentTarget.attributes['data-route'].value);
        );
    
);

这应该开始淡出,实际上是在改变路线之前等待它结束。一些警告:

    如果用户手动更改 url,它不会为您做任何事情,并且您必须将其添加到更改页面的每个逻辑中 - 为避免这些问题中的任何一个,您可能必须分开Iron-router 代码并找到一种方法来挂钩页面更改,我目前无法这样做! 我还没有测试过跨浏览器,但它在 Chrome 中运行良好。 根据我的经验,您需要小心 Meteor 中事件的 currentTarget 属性 - 我认为它不会总能满足您的期望,但这是我需要单独讨论的问题。李>

【讨论】:

谢谢,这让我走上了正确的道路。我仍然希望有一种方法可以在路由器级别执行此操作,但我真的只对对用户事件做出反应感兴趣,所以这让我到了那里。我最终在 setTimeout 函数中放置了一个 Router.Go('routeName' _id) 调用,以进行更多时间控制。 “这取决于是什么产生了页面的变化”。我同意,但是如果页面更改是由链接href="pathFor 'routeName'" 生成的,有人知道正确的模式吗? physiocoder,我无法让它与 href 模式一起使用。我将大部分页面导航移到了点击事件上,这样我就可以实现这些页面转换。它确实有将所有导航逻辑放在一个地方的好处,但它仍然感觉有点像黑客。 感谢@bryankennedy,即使使用 href 模式,我也设法启用了页面转换。需要注意的是 .render() 是异步的,因此不能保证在 onAfterAction 中有 DOM 元素可以操作。所以诀窍就是将setTimeout(function() $('element').addClass('animation');, 0); 放入onAfterAction 钩子中。希望这能有所帮助。当然不能对旧路线的淡出/消失进行动画处理,只能对新路线的动画效果进行动画处理。【参考方案2】:

在尝试将 Meteor 与 Framework7 结合时,我遇到了同样的问题。 这是绝对适合我的解决方案:

Meteor.startup(function () 
    var _animationEnd = 'oanimationend animationend webkitAnimationEnd otransitionend oTransitionEnd msTransitionEnd mozAnimationEnd MSAnimationEnd',
            _enterAnimation = 'fadeIn animated',
            _leaveAnimation = 'fadeOut animated',
            _animate = function ($el, anim, next) 
                return $el.addClass(anim)
                        .on(_animationEnd, function () 
                            $(this).removeClass(anim);
                            next && next();
                        );
            ;
    Router.onAfterAction(function () 
        _animate($(".view-main"), _enterAnimation);
    );
    $(document.body).click(function (event) 
        var $t = $(event.target).parents().andSelf().filter("[href]:last"), url;
        if ($t.size() && (url = $t.attr('href'))) 
            var currentRoute = Router.current();
            _animate($(".view-main"), _leaveAnimation, function () 
                currentRoute.redirect(url);
            );
            event.preventDefault(), event.stopPropagation();
        
    );
);

评论和优点与 richsilv 提供的解决方案:

它适用于您曾经使用过的所有模板,因为它使用 body 事件 它适用于任何元素,甚至是 a.href 的元素,因为它可以防止默认点击事件和进一步传播 它与其他浏览器更兼容,因为列出了更多“animationend/transitionend/etc”事件

【讨论】:

以上是关于在页面转换完成时暂停 Meteor 的 Iron Router 中的路由的主要内容,如果未能解决你的问题,请参考以下文章

使用 Iron Router 路由到 Meteor autoform 提交的新数据?

Iron Router 部署时显示启动页面,在本地工作正常

Meteor 或 Iron Router 是不是会干扰锚标记上的 jQuery 事件?

使用 Iron Router 在 Meteor 包中包含 HTML 模板

如何在 Iron Router Meteor 中检查当前路线

使用 blaze (meteor) 模板引擎在 Iron-icons 中设置的 Polymer 1.0 默认图标不工作