当前位置:K88软件开发文章中心编程语言JavaScriptMeteor → 文章内容

Meteor 动画

减小字体 增大字体 作者:佚名  来源:网上搜集  发布时间:2019-1-15 15:29:06

由 北公爵无欢 创建,路飞 最后一次修改 2016-08-12 动画我们现在有了实时的投票、评分和排名。然而,由于帖子在首页上跳来跳去,导致了跳动不稳的用户体验。我们用动画来平滑这种过渡。介绍 _uihooks_uihooks 相对较新,Blaze 文档也未包含该特性。正如其名称所示,它提供了每当插入、删除或动画元素时可以被触发的 hooks。Hooks 的全部清单如下:insertElement: 当新元素被插入时调用。moveElement: 当元素被移动时调用。removeElement: 当元素被删除时调用。一旦定义,这些 hooks 就会替代 Meteor 的默认行为。换句话说,Meteor 会用我们规定的行为来替代默认的插入、移动或删除元素的行为 ———— 这由我们来确定这行为会真正地工作!Meteor 与 DOM在我们开始有趣部分(使东西移动)之前,我们需要理解 Meteor 如何与 DOM(Document Object Model————组成页面内容的 HTML 元素集合)交互的。要记住的最关键的一点是,DOM 元素不能真正被“移动”;但是,它们可以被删除,被创建(注意,这是 DOM 本身的限制,而不是 Meteor 的)。所以要给元素 A 和 B 互换位置的错觉,Meteor 实际上会删除元素 B,并在元素 A 前插入一个全新的副本(B')。这使得动画有点麻烦,因为我们不能只是把 B 动画移动到新位置,因为 B 在 Meteor 重新渲染页面时就会消失(由于响应性,这瞬间发生)。但请不要担心,我们会找到一个解决办法。苏联赛跑者不过首先,让我们讲个故事。在 1980 年,正值冷战。奥运会正在莫斯科举行,苏联决心不惜任何代价要赢得 100 米短跑的金牌。所以,一群聪明的苏联科学家为其中一名运动员装备了一台传送器,只要枪声一响,那名运动员就会瞬间消失,通过时空连续的作用直接出现在终点线上。还好,赛事官员立刻注意到了这个违规行为,这名运动员没有办法只好又瞬时移动回到起跑器上,才能被允许像其他选手一样赛跑参赛。我的历史资料没有那么可靠,所以你应该对这个故事半信半疑。但是,尽量尝试记住“有传送器的苏联赛跑者”这个比喻,我们要在这一章中用到这一点。分解当 Meteor 接收到更新并实时地更改 DOM 时,我们的帖子会立即传送到它的终点位置,就像苏联赛跑者一样。但是不论是在奥运会还是在我们的应用中,我们不能瞬移任何东西。所以我们需要把元件传送回到“起跑器”上,使它“跑”(换句话说,“动画”它)到终点。所以交换帖子 A 和 B (分别位于 p1 和 p2 位置),我们会经过如下步骤:删除 B在 DOM 中,在 A 之前创建 B'传送 B' 到 p2 位置传送 A 到 p1 位置动画 A 到 p2 位置动画 B' 到 p1 位置下面图表详细解释上述步骤:再次说明,第 3 、4 步中,我们没有动画 A 和 B' 到它们的位置,而是瞬间“传送”了它们。因为这是瞬间发生的,这会产生 B 没有被删除的幻觉,并且两个元素被动画到了它们的新位置。默认情况下,Meteor 负责步骤 1 和 2,我们自己很容易重新实施它们。在步骤 5 和 6 中所有我们在做的事情是移动元素到正确的位置。因此,唯一我们真正需要担心的部分是步骤 3 和 4,即,发送元素到动画的起点。CSS 定位为了在页面中动画渲染的帖子,我们必须用到 CSS 样式。让我们按顺序快速浏览 CSS 定位。页面元素默认使用静态定位。静态定位的元素适应页面内容流,它们在屏幕上的坐标不能更改或动画。另一方面,相对定位是说元素也同样适应页面内容流,但是可以相对于原始位置进行定位。绝对定位更进一步,允许你规定元素的 x/y 坐标,坐标相对于文档或第一个绝对或相对定位的父元素。我们使用相对定位来动画我们的帖子。我们已经为你准备好了 CSS,你需要做的就是将代码添加到你的样式表中:.post{ position:relative;}.post.animate{ transition:all 300ms 0ms ease-in;}注意我们只动画有 .animate CSS 的帖子。通过添加或删除 CSS 名来控制是否添加动画效果。这使步骤 5 和 6 变得简单:我们需要做的是重置 top 坐标值为 0px(默认值),帖子就会回到它们“正常的”位置。基本上,我们仅有的挑战是搞明白元素要从相对于它们新位置的哪里开始动画(步骤 3 和 4),换句话说,它们要偏移多少。但这也不难:正确的偏移量就是帖子的原来位置减去它的新位置。使用 _uihooks既然我们了解了为帖子列表添加动画的各种因素,我们算是准备好开始添加动画了。我们首先需要把帖子列表放入一个新的 .wrapper 容器元素中:<template name="postsList"> <div class="posts page"> <div class="wrapper"> {{#each posts}} {{> postItem}} {{/each}} </div> {{#if nextPath}} <a class="load-more" href="{{nextPath}}">Load more</a> {{else}} {{#unless ready}} {{> spinner}} {{/unless}} {{/if}} </div></template>现在让我们加入 _uihooks。在模板 onRendered 回调函数中,选择 .wrapper div,并定义一个 moveElement 的 hook。Template.postsList.onRendered(function () { this.find('.wrapper')._uihooks = { moveElement: function (node, next) { // 现在不做任何事情 } }});刚刚定义的 moveElement 会在元素位置改变时被调用,从而取代 Blaze 的默认行为。由于现在这个函数还是空的,意味着什么都不会发生。去试一下:打开“Best”最佳帖子页面,给一些帖子投票:帖子排序不会发生变化,除非强制刷新(刷新页面或改变路径)。我们已经验证 _uihooks 可以工作,现在让我们来动画它!帖子排序的动画效果moveElement hook 接受两个参数:node 和 next。node 是当前正在移动到新位置的 DOM 元素next 是 node 移动的新位置之后的元素了解这些之后,我们可以逐一实现如下动画过程(如果你需要刷新一下你的记忆,可参考之前“苏联赛跑者”的例子)。当一个新的位置改变发生时,我们将:在 next 前插入 node(换句话说,如果我们没有指定任何 moveElement hook 的话,默认行为就会发生)。移动 node 回到它的起始位置。微调 node 和 next 之间的每个元素,为 node 腾出空间。动画所有元素回到它们的新默认位置。我们通过 jQuery 的魔力来做这些事情,这也是迄今为止最好的操作 DOM 的 JavaScript 库。jQuery 已经超出本书范围,但是让我们快速浏览一下我们即将用到的 jQuery 方法:$():使任

[1] [2]  下一页


Meteor 动画