首頁 web前端 js教程 給angular加上動畫效遇到的問題總結_AngularJS

給angular加上動畫效遇到的問題總結_AngularJS

May 16, 2016 pm 03:15 PM
angular 動畫效果

加入「動效」是讓使用者對應用的行為進行感知的一種有效手段。 「列表」是應用程式中最常使用的一種介面形式,經常會有添加行,刪除行,移動行這些操作。設想新增的操作很簡單,刪除時從大到小,然後消失;新增時從小到大;移動就是先刪除再新增。感覺上不複雜,應該利用CSS的transition就能搞定,可是實際做起來發現有不少問題要處理,下面一一來。

來些簡單的測試

1、最初的版本

<div class='list'>
  <div class='row-1'>row-1</div>
  <div class='row-2'>row-2</div>
</div>
登入後複製
.list{margin:20px;background:#eee;font-size:18px;color:white;}
.row-1{background:green;overflow:hidden;padding:15px;}
.row-2{background:blue;padding:15px;}
/*demo1*/
.demo-1 .remove{-webkit-transition: height 3s linear;}
.demo-1 .remove.active{height:0;}
登入後複製
var ele = document.querySelector('.demo-1 .row-1');
ele.classList.add('remove');
ele.classList.add('active');
登入後複製

想法很簡單,透過加入「remove」類,設定動畫的效果,加入「active」修改css屬性,啟動動畫。

結果和想的不一樣,兩個問題:1、動畫並沒有運行;2、row-1並沒有消失。為什麼?首先,CSS的transition不能作用於auto的屬性,因為row-1本來並沒有設定height,所以不會產生從現有的高度變成0的動畫。第二,height=0只是設定了content區域為0,padding並沒有改變,所以還是row-1還是佔據了30px的空間。

2、指定固定的height且padding也加上動畫

調整CSS

/*demo2*/
.demo-2 .row-1{height:48px;}
.demo-2 .remove{-webkit-transition: height 3s linear, padding-top 3s linear;}
.demo-2 .row-1.remove.active{height:0;padding-top:0;padding-bottom:0;}
登入後複製

這次的效果是對的,row-1從48px邊到0,同時padding也跟著變。

3、還有沒有別的辦法呢?一定要指定height嗎? transform行不行

修改CSS

/*demo3*/
.demo-3 .remove{-webkit-transition: -webkit-transform 3s linear,padding 0s linear 3s;}
.demo-3 .row-1.remove.active{-webkit-transform-origin:0 0;-webkit-transform:scaleY(0);}
登入後複製


即使沒有設定height,透過transform執行動畫也是沒有問題的。問題是,row-1還在原來的地方,還佔空間,row-2並沒有往上挪。由此帶來個問題,動畫執行完了(包括第2個設定height的例子),row-1並沒有刪除掉,只是看不見了。

4、解決動畫執行完清除元素的問題

修改CSS

複製程式碼 程式碼如下:

.demo-4 .remove{-webkit-transition: height 3s linear, padding 3s linear, opacity 3s linear,color .5s linear;}
.demo-4 .row-1.remove.active{padding-top:0;padding-bottom:0;color:rgba(0,0,0,0);opacity:0;}

修改JS

var ele, l;
ele = document.querySelector('.demo-4 .row-1');
l = ele.addEventListener('webkitTransitionEnd', function(evt){
  if (evt.propertyName === 'height') {
    ele.style.display = 'none';   
    ele.style.height = '';
    ele.removeEventListener('webkitTransitionEnd', l, false);
  }
}, false);
ele.style.height = ele.offsetHeight + 'px';
ele.classList.add('remove');
$timeout(function(){
  ele.classList.add('active');
  ele.style.height = '0px';
});
登入後複製

這次的效果不錯。有幾個注意的地方:1、透過註冊transitionEnd事件可以捕捉到動結束;2、可以同時執行多個動效,每個東西結束都會產生transitionEnd事件,透過事件的「propertyName」可以知道是哪個屬性的動效結束了。

5.用velocity.js也試了一下

CSS不用設定
JS代碼

var ele = document.querySelector('.demo-5 .row-1');
Velocity(ele, 'slideUp', { duration: 1000 });
登入後複製

看了看執行的過程,也是修改height和padding。但是,velocity用的是requestAnimationFrame函數。我認為如果動效比較簡單,就不用再引入其他的函式庫了,直接寫出來的運作效果差不多。

6.高度搞懂了,變寬度呢?

調整CSS

.demo-6 .row-1{width:100%;}
.demo-6 .remove{-webkit-transition: width 3s linear;}
.demo-6 .row-1.remove.active{width:0%;}
登入後複製

雖然寬本身可以透過百分比進行設置,但是height不固定的問題還是存在。

7.用上JS解決變width的問題

設定CSS

.demo-7 .row-1{width:100%;height:48px;}
.demo-7 .remove{-webkit-transition: width 3s linear, opacity 3s ease;}
.demo-7 .row-1.remove.active{width:0%;opacity:0;}
登入後複製

固定了height已有动效正常了。其他的改进可参照前面的例子了。

二、一个完整的例子

完整的例子实在angular中实现的。angular实现首先一个问题就是在什么时机设置动效?因为,angular是双向绑定的,如果在controller中删除了一个对象,渲染界面的时候这个对象就没了,所以必须介入到数据绑定的过程中。angular提供ngAnimatie这个动画模块,试了一下它也确实可以完成ngRepeat列表数据更新的动效。但是要额外引入angular-animation.js,虽然不大,还是觉得不是很有必要。另外,我是在一个已经写好的框架页面上加动画,如果需要引入新的module,需要改框架文件,我觉得不好。试了试动态加载animation模块也没成功,所以就研究了一下自己怎么控制动效。

angular即使不加载animation模块,也有一个$animate,它为动效控制留出了接口。
看JS

var fnEnter = $animate.enter,
  fnLeave = $animate.leave;
$animate.enter = function() {
  var defer = $q.defer(),
    e = arguments[0],
    p = arguments[1],
    a = arguments[2],
    options = {
      addClass: 'ng-enter'
    };
  fnEnter.call($animate, e, p, a, options).then(function() {
    $animate.addClass(e, 'ng-enter-active').then(function(){
      var l = e[0].addEventListener('webkitTransitionEnd', function(){
        e[0].classList.remove('ng-enter-active');
        e[0].classList.remove('ng-enter');
        e[0].removeEventListener('webkitTransitionEnd', l, false);
        defer.resolve();
      }, false); 
    });
  });
  return defer.promise;
};
$animate.leave = function() {
  var defer = $q.defer(),
    e = arguments[0];
  $animate.addClass(e, 'ng-leave').then(function(){
    $animate.addClass(e, 'ng-leave-active').then(function(){
      var l = e[0].addEventListener('webkitTransitionEnd', function(){
        fnLeave.call($animate, e).then(function(){
          defer.resolve();
        });
      }, false);
    });
  });
  return defer.promise;
};
登入後複製

ng-repeat进行数据更新是会调用$animate服务的enters,leave和move方法,所以,要自己控制动效就要重写对应的方法。重写的时候要用$animate添加,直接在dom上设置有问题。(这一段的angular的逻辑比较底层,没有太看明白,还需要深入研究。)

另外,在移动行的位置时,要通过$timeout将删除和插入放到两个digest循环中处理,否则看不出效果。

var index = records.indexOf($scope.selected),
  r = records.splice(index, 1);
$timeout(function(){
  records.splice(index + 1, 0, r[0]);
},500);
登入後複製

angular的动画和digest循环关系密切,看了angular-animation.js的代码没看明白,还需要深入研究才行。

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

如何在Ubuntu 24.04上安裝Angular 如何在Ubuntu 24.04上安裝Angular Mar 23, 2024 pm 12:20 PM

Angular.js是一種可自由存取的JavaScript平台,用於建立動態應用程式。它允許您透過擴展HTML的語法作為模板語言,以快速、清晰地表示應用程式的各個方面。 Angular.js提供了一系列工具,可協助您編寫、更新和測試程式碼。此外,它還提供了許多功能,如路由和表單管理。本指南將討論在Ubuntu24上安裝Angular的方法。首先,您需要安裝Node.js。 Node.js是一個基於ChromeV8引擎的JavaScript運行環境,可讓您在伺服器端執行JavaScript程式碼。要在Ub

一文探究Angular中的服務端渲染(SSR) 一文探究Angular中的服務端渲染(SSR) Dec 27, 2022 pm 07:24 PM

你知道 Angular Universal 嗎?可以幫助網站提供更好的 SEO 支援哦!

如何使用PHP和Angular進行前端開發 如何使用PHP和Angular進行前端開發 May 11, 2023 pm 04:04 PM

隨著網路的快速發展,前端開發技術也不斷改進與迭代。 PHP和Angular是兩種廣泛應用於前端開發的技術。 PHP是一種伺服器端腳本語言,可以處理表單、產生動態頁面和管理存取權限等任務。而Angular是一種JavaScript的框架,可以用來開發單一頁面應用程式和建構元件化的網頁應用程式。本篇文章將介紹如何使用PHP和Angular進行前端開發,以及如何將它們

淺析angular中怎麼使用monaco-editor 淺析angular中怎麼使用monaco-editor Oct 17, 2022 pm 08:04 PM

angular中怎麼使用monaco-editor?以下這篇文章記錄下最近的一次業務中用到的 m​​onaco-editor 在 angular 中的使用,希望對大家有幫助!

淺析Angular中的獨立組件,看看怎麼使用 淺析Angular中的獨立組件,看看怎麼使用 Jun 23, 2022 pm 03:49 PM

這篇文章帶大家了解Angular中的獨立元件,看看怎麼在Angular中建立一個獨立元件,怎麼在獨立元件中導入已有的模組,希望對大家有幫助!

Vue頁面過渡動畫實現及常用動畫效果 Vue頁面過渡動畫實現及常用動畫效果 Jun 09, 2023 pm 04:11 PM

Vue是一款受歡迎的JavaScript框架,它透過資料驅動的方式,協助開發者建立互動性強、資料呈現美觀的單頁網頁應用程式。 Vue內建了許多有用的特性,其中之一就是頁面過渡動畫。在本文中,我們將介紹如何使用Vue的過渡動畫功能,並討論最常見的動畫效果。實現Vue頁面過渡動畫Vue的頁面過渡動畫是透過Vue的&lt;transition&gt;與&lt;tr

Angular元件及其顯示屬性:了解非block預設值 Angular元件及其顯示屬性:了解非block預設值 Mar 15, 2024 pm 04:51 PM

Angular框架中元件的預設顯示行為不是區塊級元素。這種設計選擇促進了元件樣式的封裝,並鼓勵開發人員有意識地定義每個元件的顯示方式。透過明確設定CSS屬性 display,Angular組件的顯示可以完全控制,從而實現所需的佈局和響應能力。

專案過大怎麼辦?如何合理拆分Angular項目? 專案過大怎麼辦?如何合理拆分Angular項目? Jul 26, 2022 pm 07:18 PM

Angular專案過大,怎麼合理拆分它?以下這篇文章跟大家介紹一下合理分割Angular專案的方法,希望對大家有幫助!

See all articles