使用Turbolinks实现页面切换动画

13

如何使用Turbolinks动画页面更改?

这是否可行?

我尝试在body上使用CSS过渡效果,但它并没有按预期工作。不知道如何只更新窗口的一部分,并在完成时进行回调,或者是否可能。

提前致谢。

2个回答

14

这样的代码可能是有效的(使用 jQuery 编写 CoffeeScript):

$(document).on 'page:fetch', ->
  $('#content').fadeOut 'slow'

$(document).on 'page:restore', ->
  $('#content').fadeIn 'slow'

你也可以使用CSS动画或一些更复杂的JavaScript。 这篇很棒的帖子深入介绍了一些例子和演示。

此外,我发现了一个turbolink transitions ruby gem(我没有测试过)。


17
这就是我最终解决问题所做的事情,这个宝石也是我创建的 =) - caarlos0
2
我应该注意到是同一个昵称。这太有趣了。哈哈。 - Scott Bartell
是的,哈哈,好吧,至少问题解决了。 - caarlos0
1
嗨,我认为这在Turbolinks 5上不起作用(重要事件已被重命名)。有升级的机会吗? - Ruby Racer

3
您无法仅使用Turbolinks更新窗口的一部分,您可能需要改用pjax。但是,您可以使用一些巧妙的方法使其看起来像在使用Turbolinks时只有页面的某个部分正在过渡和更新。
我有一个索引页面,列出了一些项目,如果单击项目,它将转到显示页面。但是从显示页面,我仍希望能够直接导航到其他项目的显示页面。在索引页面上,项目列表为六列宽,并在显示页面上缩小其宽度以腾出空间以显示详细信息。
// items.css.sass
.width-trans
  +transition(width 400ms ease-in)

定义一个简单的CSS类,用于过渡元素宽度的变化。

<!-- index.html.erb ->
<div id="target_div" class="width-trans six columns">
  <%= link_to "Item",
              item_path(@item.id),
              :'data-no-turbolink' => true,
              :class => 'trans' %>
</div>

我们在需要过渡的链接上将data-no-turbolink设置为true,这样我们就能更好地控制它们。
# items.js.coffee
$(document).on 'page:restore', (e) ->
  if window.location.href.match(/\/items\/\d$/) || window.location.href.match(/\/items$/)
    $("#target_div").removeClass("three").addClass("six")
  else
    $("#target_div").removeClass("six").addClass("three")

target_page = undefined  # Sorry, this 'target_page' stuff is a little janky.

if Modernizr.csstransitions
  eventEndNames =
    'WebkitTransition': 'webkitTransitionEnd'
    'MozTransition':    'transitionend'
    'OTransition':      'oTransitionEnd'
    'msTransition':     'MSTransitionEnd'
    'transition':       'transitionend'

  eventName = eventEndNames[Modernizr.prefixed('transition')]

  $(document).on eventName, '#target_div', () ->
    Turbolinks.visit(target_name) if target_page
    target_page = undefined

$(document).on 'click', '.trans', (e) ->
  e.preventDefault()

  target_name = e.target.href
  $(e.target).closest("#target_div").toggleClass("three six")
  false

好的,这有点疯狂,也许我们可以想出一种更通用的方法来做到这一点。但这是正在发生的事情:

我们已经在我们的.trans链接上禁用了Turbolinks,这样Turbolinks就不会立即获取新页面(我们将明确告诉Turbolinks何时获取它)。当我们点击一个.trans链接时,它会查找#target_div并切换.six和.three类。我使用Foundation,所以three和six是我的网格系统的一部分,并定义了我的div的宽度..所以当我从六变成三时,这会改变宽度。

这触发了我的CSS过渡,#target_div的宽度减小,然后它触发了过渡结束事件。当转换结束时,我们在目标URL上调用Turbolinks.visit()。

#target_div应该由索引和显示操作呈现。我们有监听page:restore的部分,它根据呈现它的操作将#target_div的列设置为六或三。

最终结果是,#target_div似乎在我们切换页面时进行动画处理,但实际上它在我们切换页面之前进行了过渡,在不同状态下呈现了相同的div。


太多的工作/代码,却没有那么多的功能。不过还是谢谢你。 - caarlos0
是的,我同意。这就是为什么我一开始就说这可能可以变成更通用的东西;也许有人会对它感兴趣,写一个可重用的基于插件的东西。 - bratsche
哦,正如我在评论开头所说的那样...你可能想考虑使用pjax。它更加灵活,可以让你更新页面的特定部分。这也是GitHub使用的方式,他们用它在页面之间进行动画切换。 - bratsche
是的,我正在看它... 我也考虑调整Turbolinks并拉取请求更改,但是现在我没有时间。无论如何,再次感谢您的回答。 - caarlos0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接