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

Meteor 动画

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

何一个 DOM 元素成为 jQuery 对象。offset():取得元素相对于文档的当前位置,返回包含 top 和 left 属性的对象。outerHeight():取得“outer”元素的高度(包括 padding 和可选的 margin)。nextUntil(selector):取得所有目标元素之后到(但不包含)匹配 selector 的元素。insertBefore(selector):在匹配 selector 的元素之前插入另一个元素。removeClass(class):如果该元素有 class CSS 类,删除它。css(propertyName, propertyValue):设置 CSS propertyName 属性为 propertyValue。height():取得该元素的高度。addClass(class):为元素添加 class CSS 类。Template.postsList.onRendered(function () { this.find('.wrapper')._uihooks = { moveElement: function (node, next) { var $node = $(node), $next = $(next); var oldTop = $node.offset().top; var height = $node.outerHeight(true); // 找出 next 与 node 之间所有的元素 var $inBetween = $next.nextUntil(node); if ($inBetween.length === 0) $inBetween = $node.nextUntil(next); // 把 node 放在预订位置 $node.insertBefore(next); // 测量新 top 偏移坐标 var newTop = $node.offset().top; // 将 node *移回*至原始所在位置 $node .removeClass('animate') .css('top', oldTop - newTop); // push every other element down (or up) to put them back $inBetween .removeClass('animate') .css('top', oldTop < newTop ? height : -1 * height); // 强制重绘 $node.offset(); // 动画,重置所有元素的 top 坐标为 0 $node.addClass('animate').css('top', 0); $inBetween.addClass('animate').css('top', 0); } }});注解:我们计算 $node 的高度,便于知道要偏移 $inBetween 的元素多少距离。我们使用 outerHeight(true) 使 margin 和 padding 加入计算中。在 DOM 中,我们不知道 next 是在 node 之前还是之后,所以我们在定义 $inBetween 时同时考虑这两种情况。为了在“传送 teleporting”和“动画 animating”元素之间转换,我们简单地 toggle animate CSS 类(在 CSS 样式表中定义了实际动画)。由于我们用相对定位,所以我们总可以通过重置任何元素的 top 属性值为 0 来把元素归位到应在位置。强制 Redraw你也许在想 $node.offset() 这行代码。为什么我们不打算移动 $node,而去关心它的位置呢?要这么想:如果你告诉一台有完美逻辑的机器人向北奔跑 5 千米,跑完后再跑回起点,它也许认为既然又回到起点,那么何不节省能量而待在原地。所以为了确保机器人能跑完 10 千米,我们会告诉它在跑到 5 千米时记录它的坐标才能转向。浏览器以相似的方式工作:如果我们在同一时间只给出 css('top', oldTop - newTop) 和 css('top', 0) 的话,新坐标就会简单地替换旧坐标,什么也不会发生。如果我们想真正地看到动画,就需要强制浏览器去在元素改变位置后重新绘制它。一个简单的强制重绘的方法是让浏览器检查元素的 offset 属性————再次重绘元素才能让浏览器识别它。让我们再试一次。回到“Best”最佳帖子页面,给帖子投票:现在应该可以看到帖子如芭蕾舞般优雅地上下滑动。Can't Fade Me既然我们已经搞定比较难的重新排序,那么插入和删除帖子的动画就是小菜一碟了!首先,我们渐入新帖子(注意为了简单,我们在此用 JavaScript 动画):Template.postsList.onRendered(function () { this.find('.wrapper')._uihooks = { insertElement: function (node, next) { $(node) .hide() .insertBefore(next) .fadeIn(); }, moveElement: function (node, next) { //... } }});为了更好看到效果,我们通过控制台插入新帖子,来测试动画:Meteor.call('postInsert', {url: 'http://apple.com', title: 'Testing Animations'})其次,我们动画淡出删除的帖子:Template.postsList.onRendered(function () { this.find('.wrapper')._uihooks = { insertElement: function (node, next) { $(node) .hide() .insertBefore(next) .fadeIn(); }, moveElement: function (node, next) { //... }, removeElement: function(node) { $(node).fadeOut(function() { $(this).remove(); }); } }});再次,在控制台(用 Posts.remove('somePostId'))删除一个帖子来测试动画效果。页面过渡到目前为止,我们已经在页面内动画了元素。但是如果我们想添加页面之间的过渡动画呢?页面过渡是 Iron Router 的任务。点击一个链接,{{> yield}} helper 的内容自动地更换。就像我们为帖子列表改变 Blaze 默认行为一样,我们也可以为 {{> yield}} 做同样的事情,在不同路由之间添加渐隐过渡动画效果!如果我们想渐入渐隐页面,我们必须要确保它们在各自上方显示。我们用添加了 position:absolute 属性的 .page container div 来包裹每个页面模板。但不能相对于窗口来绝对定位我们的页面,因为这样页面会覆盖应用的 header。所以我们给 #main div 添加 position:relative 以便 .page div 的 position:absolute 会得到其正确位置。为了节省时间,我们已经在 sytle.css 中添加了必要的 CSS 代码://...#main{ position: relative;}.page{ position: absolute; top: 0px; width: 100%;}//...是时候添加页面过渡代码了。代码看起来很熟悉,因为这和我们添加和删除帖子时的代码完全一致:Template.layout.onRendered(function() { this.find('#main')._uihooks = { insertElement: function(node, next) { $(node) .hide() .insertBefore(next) .fadeIn(); }, removeElement: function(node) { $(node).fadeOut(function() { $(this).remove(); }); } }});我们刚刚看了一些为 Meteor 应用添加动画元素的模式。虽然这不是一个详尽的清单,但是希望这会提供一个基础,在其上去构建更复杂的过渡动画。

上一页  [1] [2] 


Meteor 动画