ปิดการใช้งาน nganimate สำหรับบางองค์ประกอบ


96

ฉันใช้โมดูล ngAnimate แต่ทั้งหมดของฉันng-if, ng-showฯลฯ รับผลกระทบจากที่ผมต้องการที่จะยกระดับ ngAnimate สำหรับองค์ประกอบที่เลือกบาง สำหรับประสิทธิภาพและข้อบกพร่องบางอย่างในองค์ประกอบที่แสดงและซ่อนอย่างรวดเร็ว

ขอบคุณ.


1
เพิ่มโค้ดตัวอย่างของปัญหา
cheekybastard

หนึ่งในประเด็นคือ ngAnimate บังคับให้พนักงานdisplay:blockทุกคนของคุณ:ng-hide-add-active, .ng-hide-remove { display: block!important; }
Somatik

คำถามที่ดีกว่าที่จะถามคือ "ฉันจะกำหนด CSS ของฉันได้อย่างไรเพื่อให้ ngAnimate ทำงานอย่างถูกต้องสำหรับองค์ประกอบที่ซ่อนอยู่โดยไม่ต้องวนรอบภาพเคลื่อนไหวแบบเต็ม" คำตอบที่ดีที่สุดคือจาก Chris Barr ด้านล่าง
Eric

คำตอบ:


53

เพียงเพิ่มสิ่งนี้ลงใน CSS ของคุณ จะดีที่สุดถ้าเป็นกฎสุดท้าย:

.no-animate {
   -webkit-transition: none !important;
   transition: none !important;
}

จากนั้นเพิ่มลงno-animateในคลาสขององค์ประกอบที่คุณต้องการปิดใช้งาน ตัวอย่าง:

<div class="no-animate"></div>

2
หากคุณใช้ sass คุณไม่จำเป็นต้องใช้ "-webkit-transition: none! important;"
Marwen Trabelsi

15
โปรดทราบว่าคำตอบนี้ไม่ถูกต้องเนื่องจากมันปิดการใช้งานภาพเคลื่อนไหวทั้งหมดไม่ใช่เฉพาะที่จัดการโดย Angular
stackular

1
คุณลองหรือยัง? ขอดูตัวอย่างรหัสของคุณ ได้ผลสำหรับฉันและคนมากกว่าหกคนที่อนุมัติ
David Addoteye

2
ฉันเพิ่ม.no-animate, .no-animate-children *กฎเพื่อให้ครอบคลุมเด็ก ๆ ฯลฯ
Kimball Robinson

1
@DavidAddoteye โซลูชันนี้ใช้ไม่ได้หากคุณมี ng-show หรือ ng-if ในองค์ประกอบที่มีการเปลี่ยนแปลง .. ฉันหมายถึง .. ถ้าฉันมีสปินเนอร์ตัวโหลดที่แสดงเฉพาะในระหว่างคำขอ http และหายไปเมื่อคำขอได้รับการแก้ไขให้เพิ่ม คลาสนี้จะส่งผลให้ไม่มีการเคลื่อนไหวเลย! คำตอบของไมเคิลก็โอเค แต่น่าเบื่อเกินไปที่จะนำไปใช้และคุณควรพยายามหลีกเลี่ยงตัวเลือก css ในคอนโทรลเลอร์ การสร้างคำสั่งนั้นใช้ได้ แต่เมื่อดูคำตอบของ Blowsie คุณจะพบว่าทีม AngularJS ได้ให้วิธีการที่ยืดหยุ่นในการดูแลปัญหานี้แล้ว;)
edrian

106

หากคุณต้องการเปิดใช้งานแอนิเมชั่นสำหรับองค์ประกอบเฉพาะ (ซึ่งต่างจากการปิดใช้งานสำหรับองค์ประกอบเฉพาะ) คุณสามารถใช้$ animateProviderเพื่อกำหนดค่าองค์ประกอบด้วยชื่อคลาสเฉพาะ (หรือ regex) เพื่อทำให้เคลื่อนไหวได้

โค้ดด้านล่างนี้จะเปิดใช้งานภาพเคลื่อนไหวสำหรับองค์ประกอบที่มีangular-animateคลาส:

var myApp = angular.module("MyApp", ["ngAnimate"]);
myApp.config(function($animateProvider) {
  $animateProvider.classNameFilter(/angular-animate/);
})

นี่คือตัวอย่างมาร์กอัปที่มีangular-animateคลาสเพื่อเปิดใช้งานภาพเคลื่อนไหว:

<div ng-init="items=[1,2,3,4,5,6,7,8,9]">
  <input placeholder="Filter with animations." ng-model="f" /> 
  <div class="my-repeat-animation angular-animate" ng-repeat="item in items | filter:f track by item" >
    {{item}}
  </div>
</div>

ตัวอย่างPlunkerยืมและแก้ไขจากบล็อกนี้ซึ่งมีเพียงตัวกรองแรกเท่านั้นที่มีภาพเคลื่อนไหว (เนื่องจากมีangular-animateคลาส)

โปรดทราบว่าฉันใช้angular-animateเป็นตัวอย่างและสามารถกำหนดค่าได้อย่างสมบูรณ์โดยใช้.classNameFilterฟังก์ชัน


5
คุณช่วยวันของฉัน ขอบคุณมาก
gustavohenke

นี่เป็นวิธีการแก้ปัญหาที่สวยงามที่สุดเนื่องจากต้องเลือกใช้สำหรับภาพเคลื่อนไหวและองค์ประกอบที่เคลื่อนไหวจะแตกต่างอย่างชัดเจนจากชื่อคลาสอื่น ๆ
Nikola M.

2
นี่ควรเป็นทางออกที่ได้รับการยอมรับ ทำงานได้อย่างสมบูรณ์แบบและบันทึกวันของฉัน!

9
ใช้/^(?:(?!ng-animate-disabled).)*$/regex เพื่อปิดการใช้งานคำอธิบายประกอบกับng-animate-disabledคลาส
IcanDivideBy0

ทางออกที่ดี! ฉันมีตารางที่มีเลขหน้า 20 แถวต่อหน้า หนึ่งในสามของเวลาในการสลับหน้าถูกเบราว์เซอร์ใช้การประมวลผลคลาส css ของแอนิเมชั่นที่ไม่ได้ใช้งานด้วยซ้ำ
Kevin

81

มีสองวิธีที่คุณสามารถแยกภาพเคลื่อนไหวใน AngularJS ได้หากคุณมีโมดูล ngAnimate เป็นการพึ่งพาโมดูลของคุณ:

  1. ปิดหรือเปิดใช้งานแอนิเมชั่นทั่วโลกบนบริการ $ animate:

    $animate.enabled(false);
    
  2. ปิดการใช้งานแอนิเมชั่นสำหรับองค์ประกอบเฉพาะ - ต้องเป็นองค์ประกอบสำหรับเชิงมุมนั้นจึงจะเพิ่มคลาส animationstate css (เช่น ng-enter, ... )!

    $animate.enabled(false, theElement);
    

ในเวอร์ชัน Angular 1.4 คุณควรย้อนกลับอาร์กิวเมนต์:

$animate.enabled(theElement, false);

เอกสารประกอบสำหรับ$animate .


2
สิ่งนี้ใช้ไม่ได้กับองค์ประกอบเฉพาะตามที่คาดไว้ หากฉันปิดภาพเคลื่อนไหวทั่วโลกแล้วเปิดใช้งานในองค์ประกอบใดองค์ประกอบหนึ่งก็จะไม่ทำงาน
Kushagra Gour

1
คำตอบนี้ควรถูกลบหรือแก้ไขเพื่อระบุว่า Angular เวอร์ชันใดใช้งานได้จริง สำหรับ 1.2.10 มันไม่สามารถใช้งานได้อย่างแน่นอนสำหรับการเปิดใช้งานแอนิเมชั่นแบบเลือกสำหรับองค์ประกอบบางอย่างซึ่งเป็นจุดรวมของคำถาม AFAICT
Trindaz

ไม่มีใครรู้ว่าตัวเลือก 2 ทำงานบนเวอร์ชัน 1.2.25 หรือไม่?
khorvat

1
เพียงแค่ดูเอกสาร ( docs.angularjs.org/api/ng/service/$animate ) ดูเหมือนว่า«องค์ประกอบ»เป็นพารามิเตอร์แรกที่จะส่งไปยังฟังก์ชันที่เปิดใช้งาน
DanielM

49

หากต้องการปิดใช้งาน ng-animate สำหรับองค์ประกอบบางอย่างโดยใช้คลาส CSS ซึ่งเป็นไปตาม Angular animate paradigm คุณสามารถกำหนดค่า ng-animate เพื่อทดสอบคลาสโดยใช้ regex

Config

    var myApp = angular.module("MyApp", ["ngAnimate"]);
    myApp.config(function($animateProvider) {
        $animateProvider.classNameFilter(/^(?:(?!ng-animate-disabled).)*$/);
    })

การใช้งาน

เพียงเพิ่มng-animate-disabledคลาสให้กับองค์ประกอบใด ๆ ที่คุณต้องการให้ ng-animate เพิกเฉย


เครดิต http://davidchin.me/blog/disable-nganimate-for-selected-elements/


7
ฉันคิดว่านี่เป็นวิธีกรองพฤติกรรมที่ถูกต้องที่สุด!
edrian

6
มันคุ้มค่าที่จะเลื่อนดูคำตอบนี้
Jossef Harush

ฉันสามารถยืนยันได้ว่าด้วย AngularJS เวอร์ชันล่าสุดนี่เป็นทางออกที่ดีที่สุดสำหรับปัญหานี้แน่นอน
Adam Reis

44

ขอบคุณฉันเขียนคำสั่งที่คุณสามารถวางไว้บนองค์ประกอบได้

CoffeeScript:

myApp.directive "disableAnimate", ($animate) ->
  (scope, element) ->
    $animate.enabled(false, element)

JavaScript:

myApp.directive("disableAnimate", function ($animate) {
    return function (scope, element) {
        $animate.enabled(false, element);
    };
});

นี่เป็นวิธีการที่ค่อนข้างดีมันไม่ชัดเจนเสมอไปว่าจะเข้าถึงออบเจ็กต์องค์ประกอบได้อย่างไรและด้วยวิธีการอื่น ๆ บางอย่างฉันกลัวว่าฉันจะทำให้คอนโทรลเลอร์ของฉันยุ่งเหยิงด้วย Javascript ที่อ้างอิงยากหนึ่งหรือหลายองค์ประกอบที่กำหนดไว้ในเทมเพลต . รู้สึกเหมือนเป็นการแยกความกังวลความรุ่งโรจน์!
Mattygabe

2
คำสั่งพารามิเตอร์ถูกย้อนกลับใน $ animate.enabled หากใครสงสัยว่าเหตุใดจึงปิดใช้งานภาพเคลื่อนไหว ng ทั้งหมด ใช้งานได้เหมือนมีเสน่ห์หากคุณใช้$animate.enabled(element,false);
gss

ขออภัยฉันเห็นว่าใช้ได้กับ 1.4.x + เท่านั้นรหัสด้านบนถูกต้องสำหรับเวอร์ชันก่อนหน้า
gss

19

ฉันพบว่า$animate.enabled(false, $element);จะใช้ได้กับองค์ประกอบที่ใช้ng-showหรือng-hideแต่จะใช้ไม่ได้กับองค์ประกอบที่ใช้ng-ifด้วยเหตุผลบางประการ! วิธีการแก้ปัญหาที่ฉันสิ้นสุดที่ใช้คือการทำมันทั้งหมดใน CSS ซึ่งผมได้เรียนรู้จากกระทู้นี้บน GitHub

CSS

/* Use this for transitions */
.disable-animations.ng-enter,
.disable-animations.ng-leave,
.disable-animations.ng-animate {
  -webkit-transition: none !important;
  transition: none !important;
}

/* Use this for keyframe animations */
.disable-animations.ng-animate {
  -webkit-animation: none 0s;
  animation: none 0s;
}

วทส

.disable-animations {
  // Use this for transitions
  &.ng-enter,
  &.ng-leave,
  &.ng-animate {
    -webkit-transition: none !important;
    transition: none !important;
  }
  // Use this for keyframe animations
  &.ng-animate {
    -webkit-animation: none 0s;
    animation: none 0s;
  }
}

กรณีของฉันคือเมื่อโหลด ngAnimate คลาสเช่น. load.ng-hide จะยังคงอยู่บนหน้าจอจนกว่าการวนรอบภาพเคลื่อนไหวแบบเต็มจะเสร็จสิ้น นี่เป็นคำตอบที่สะอาดที่สุดเพราะโดยพื้นฐานแล้วเพียงแค่ป้อนการกำหนดค่าที่เหมาะสมให้กับ ngAnimate และใช้งานตามปกติ วิธีนี้ดีกว่าที่จะกำหนดค่าไม่ถูกต้องจากนั้นปิดการใช้งาน ดังนั้น +1 สำหรับคุณหวังว่าฉันจะให้มากกว่านี้เพื่อให้คะแนนที่นี่
Eric

นี่คือคำตอบที่ยุ่งยากที่สุด ทำด้วย css ดีกว่าไปยุ่งกับ js
มนัส

โปรดดูที่คำตอบของ @Blowsie นั่นเป็นวิธีทั่วไปและถูกต้องกว่าในการจัดการกับสิ่งนี้
edrian

3

ฉันไม่ต้องการใช้ ngAnimate กับฉันng-ifดังนั้นนี่จะเป็นทางออกของฉัน:

[ng-if] {
  .ng-enter, .ng-leave, .ng-animate {
    -webkit-transition: none !important;
    transition: none !important;
  }
}

เพียงโพสต์นี้เป็นข้อเสนอแนะอื่น!


2

ฉันมีรายการที่รายการแรกliถูกซ่อนไว้โดยใช้ng-hide="$first". ใช้ng-enterผลลัพธ์ในliการแสดงเป็นเวลาครึ่งวินาทีก่อนที่จะหายไป

จากการแก้ปัญหาของ Chris Barr ตอนนี้รหัสของฉันมีลักษณะดังนี้:

HTML

<ol>
    <li ng-repeat="item in items"
        ng-hide="$first"
        ng-class="{'no-animate' : $first}">
    </li>
</ol>

CSS

.no-animate.ng-enter,
.no-animate.ng-leave,
.no-animate.ng-animate {
        transition: none !important; /* disable transitions */
        animation: none 0s !important; /* disable keyframe animations */
}

li.ng-enter {
    opacity: 0;
    transition: opacity 0.3s ease-out;
}
li.ng-enter-active {
    opacity: 1;
}

/* I use Autoprefixer. If you don't, please include vendor prefixes. */

0

ฉันรู้ว่ามันเป็นการตอบกลับล่าช้า แต่ที่นี่เราใช้ใน MainController:

// disable all animations
$animate.enabled(false);

แต่ปัญหาก็คือว่าเมื่อเราปิดการใช้งานภาพเคลื่อนไหวทุก opacity: 0UI-เลือกมีการกำหนดให้

ดังนั้นจึงจำเป็นต้องตั้งค่าความทึบเป็น 1 โดยใช้ CSS:

.ui-select-choices {
    opacity: 1 !important;
}

สิ่งนี้จะตั้งค่าความทึบอย่างถูกต้องและ ui-select จะทำงาน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.