Angular.js: يتأخر ng-show / hide على عنصر متحرك

تم إنشاؤها على ١٦ يوليو ٢٠١٤  ·  17تعليقات  ·  مصدر: angular/angular.js

هذا ليس سلوكًا متوقعًا إذا كنت تقوم بعمل رسوم متحركة ثابتة على شيء مثل أداة التحميل الدوارة وتريد فقط إخفاءها أو إظهارها على الفور.

لم يُطلب من ng-animate إدارة العنصر ، فأنا أريد فقط أن يحدث ng-show / hide العادي على الفور ، وأعتقد أن أي رسوم متحركة css مستمرة يجب أن تكون غير ذات صلة ، على ما أعتقد.

كمان: http://jsfiddle.net/PvS8k/2/

قم بإلغاء تحديد "محمل العرض" ولاحظ أن الأمر يستغرق بضع ثوانٍ حتى تختفي بالفعل.

أعتقد أن هذا تغيير حديث لأن أداة التحميل الخاصة بنا لم تكن مثبتة في تطبيقنا قبل الترقية. أعتقد أننا كنا على 1.12 من قبل.

يجب أن أفتقد شيئًا ما في فهمي لكيفية استخدام / عدم استخدام ng-animate ، أليس كذلك؟ في هذه الحالة ، أرغب بالفعل في عدم استخدامه ، ولكن إذا كان بإمكاني استخدامه لتجاهل هذا العنصر ، فسيعمل ذلك أيضًا. بالتأكيد سلوك مفاجئ بالرغم من ذلك.

ngAnimate broken expected use bug

التعليق الأكثر فائدة

@ tole42 هذا هو الحل:

.YourElementClass.ng-animate { -webkit-animation: none 0s; }

ال 17 كومينتر

إن ngAnimate جشع لأنه يفترض أن جميع إطارات المفاتيح / كود الانتقال النشط على العنصر أثناء أي من المشغلات موجودة ليتم تحريكها عبر ngAnimate. لذلك ، في هذه الحالة ، على الرغم من أن .loader ليس له علاقة بـ ngShow / ngHide ، لا يزال يتم انتقاؤه كرسوم متحركة صالحة.

للتغلب على هذا ، قم بمسح نمط الرسوم المتحركة ببساطة عند تطبيق فئة .ng-animate على العنصر.

http://jsfiddle.net/PvS8k/4/

هذه مشكلة في وراثة CSS. إذا كانت هناك طريقة أفضل لاكتشاف الأنماط دون الحاجة إلى الاعتماد فقط على getComputedStyle ، فيمكن تجنب هذه الأنواع من المراوغات.

@ ماتسكو أعتقد أن هذه الحالة الخاصة هي في الواقع انحدار. كما ترى في مكبس SimpleAsCouldBe ، أو في هذا المكبس http://plnkr.co/edit/5cfIXfNryNOzK66q9YWL؟p=preview ، في 1.2.17 ، لا يختفي العنصر على الفور ، ولكن في 1.2.16 ، يفعل. هذا على الأرجح بسبب https://github.com/angular/angular.js/commit/55b2f0e8620465559016b424967d90a86af597c0
أعتقد أن هذا يستدعي إجراء فحص دقيق قليلاً ؛ على الأقل يجب أن يكون هناك ملاحظة في سجل التغيير والمستندات حول هذا الموضوع.

شكرًا على الحل البديل ، إنه يقوم بالخدعة كما هو متوقع.

نقطتان. أحدهما خاص بـ ng-show والآخر عام.

ng-show + الرسوم المتحركة اللانهائية:

هل يجب أن تؤخر الرسوم المتحركة اللانهائية _really_ إخفاء ng-show ؟ حاولت عد الثواني ولا تنتظر دائمًا 4 ثوان لإخفائها. في بعض الأحيان يبدو أن الرقم 5 أو 7 ... يختلف. أيضًا إذا قمت بقلب مربع الاختيار وإيقاف تشغيله مرة أخرى ، فلن يختبئ أبدًا. أعتقد أن هناك خطأ حقيقي يختبئ هنا في مكان ما.

محبوب

بصفتي شخصًا غير مساهم ، ليس لدي الكثير من الكلام ، ولكن ربما لا يكون إلغاء الاشتراك هو الاستراتيجية الصحيحة لهذه المكتبة. إنه لأمر سحري مذهل أن يكون لديك مكتبة JS تتفاعل مع قواعد CSS .. إذا اضطررت إلى تمييز العناصر بـ ng-animatable سأكون أكثر استعدادًا لذلك.

SimpleAsCouldBe نعم لقد كنت أفكر في نفس الشيء أنه ربما يكون من الأفضل طلب جميع الرسوم المتحركة لبادئة فئة animate- بحيث يتم ربط ngAnimate بالرسوم المتحركة.

فيما يتعلق بالتأخير ، لا يعني ذلك وجود تأخير ، بل إن ngAnimate يلغي الجزء اللانهائي ويقوم بتشغيل الرسوم المتحركة مرة واحدة فقط. لذلك ، عند إخفائه ، فإنه ينتظر 2 ثانية * 1.5 = 3 ثوانٍ ثم يقوم بتشغيل فحص المهلة وإغلاق الرسوم المتحركة. لذلك فهي فترة زمنية غير ضرورية ولا ينبغي أن تكون موجودة على الإطلاق - فقط اكتشاف نمط CSS محدود للغاية.

Narretz بينما قد يؤثر الالتزام الذي قدمته في هذا المثال بالذات ، إلا أنه في الواقع لا علاقة له بالانحدار. والسبب في ذلك هو أن التصميم .ng-hide الذي كان موجودًا قبل الإصلاح يطبق قيمة display:none في وقت مختلف. لكن الإصلاح الحالي ينطبق عليه فقط بعد الانتهاء من جميع الرسوم المتحركة (بمجرد إزالة فئة .ng-animate ).

ألق نظرة على العرض أدناه. شاهد كيف توجد مجموعتان من المحددات لفئة .blue : واحدة مع .ng-animate وبدونها. على الرغم من تطبيق فئة .blue على الفور ، لا يزال ngAnimate يعتقد أن الرسوم المتحركة مستحقة وستنتظر 3s (تذكر 2s * 1.5) قبل تطبيق مهلة الإغلاق. عادةً ما تكون ثانيتين ، لكن حدث animationend لا يتم إطلاقه أبدًا لأن الرسوم المتحركة الفعلية على العنصر (التي توجد بسبب .loader ) لا نهائية ولا يتم تشغيلها بواسطة فئة ng ( أو ng-show للمثال السابق). حتى يقال أن هذا لا يتأثر بسبب إصلاح الخلل السابق.
http://jsfiddle.net/PvS8k/15/

قد يكون من الأفضل جعل ngAnimate أقل سذاجة ويتم تحريكه فقط عندما يكون animated- موجودًا كبادئة CSS في مكان ما.

أعتقد أنه إذا كنت منفتحًا على تغيير جذري مثل التعامل مع الرسوم المتحركة ، فسيؤدي ذلك إلى إنشاء تجربة مطور أقل إثارة للدهشة.

هل ستكون منفتحًا على البادئة بشيء محدد الزاوية مثل .ng-animate بدلاً من .animate عادي؟

لدي نفس المشكلة:
مع الزاوي> = 1.2.17 http://jsfiddle.net/9krLr/17/
مع 1.2.16 الزاوي كل شيء على ما يرام: http://jsfiddle.net/EZpQQ/1/

@ tole42 هذا هو الحل:

.YourElementClass.ng-animate { -webkit-animation: none 0s; }

شكرا لمساعدتك. الحل لا يعمل :(
ما الخطأ؟
http://jsfiddle.net/9krLr/21/

@ tole42 لا شيء في هذا الكمان

أعتقد أنني أرى نفس المشكلة مثل @ tole42 . مع تضمين ngAnimate في وحدة نمطية ، لا تعمل وظيفة ng-hide / ng-show القياسية بشكل صحيح للحالة الأساسية عندما لا تحاول تحريكها. بمعنى آخر ، عند استخدام ng-hide / ng-show على عنصر عادي بدون تطبيق فئة الرسوم المتحركة.

<div ng-hide="hideme">hide me</div>

إذا أردت رسمًا متحركًا على هذا الإخفاء ، فسأفعل شيئًا مثل:

<div ng-hide="hideme" class="myanimation">hide me</div>

هناك بعض الحالات في أحد التطبيقات حيث قد ترغب في تحريك عرض / إخفاء وحالات أخرى لا ترغب في تحريكها. في الحالات التي لا تريد فيها الحركة ، لا يمكنك تزيين العنصر الذي يتم إظهاره / إخفاؤه بأي فئة رسوم متحركة مخصصة. في هذه الحالة ، يضيف Angular فئة "ng-hide" إلى عنصر مخفي.

إذا لم تقم بتضمين ngAnimate في الوحدة الخاصة بك على الإطلاق ، فهذا يعمل كما هو متوقع: يختفي العنصر على الفور. ولكن بمجرد تضمين ngAnimate ، تحصل على السلوك الموضح في العبارتين اللتين نشرتهما @ tole42 : هناك تأخير قبل أن يختفي العنصر الذي تمت إضافة فئة "ng-hide" إليه بالفعل. يجب أن تختفي على الفور إذا كنت لا تحاول استخدام الرسوم المتحركة عليها.

هناك نوعان من الحلول التي يبدو أنها تعمل:

.ng-hide-add {
    transition: 0s linear all;
}

أو:

.ng-hide {
    display: none !important;
}

لكن لا يبدو من الصحيح أن هذه الأشياء يجب أن تكون ضرورية في الحالة التي تحاول فيها ببساطة إخفاء شيء ما بطريقة غير متحركة.

فقط لمتابعة بعض الاكتشافات الإضافية ...

محاولة تلخيص المشكلة في أبسط سيناريو ممكن - إظهار / إخفاء عناصر div العادية - لا تظهر المشكلة.

لقد لاحظت في العبارات التي نشرها ويوضح المثال مشكلة إظهار / إخفاء حقول الإدخال. كانت تجربتي مماثلة (رؤية بيان المشكلة مع حقول الإدخال) ، ولكن باستخدام bootstrap.css. عند البحث في كلا ملفي css عن كثب ، يقوم كلاهما بتطبيق انتقالات css على حقول الإدخال.

يبدو أن انتقالات css هي الجاني الحقيقي ، حيث تلتقط حركة الزاوي المدد منها. هذا هو سبب التأخير البصري عند إظهار / إخفاء تلك العناصر ، حتى لو لم تكن تحاول عن قصد تحريك هذا الانتقال.

لذلك لا أعتقد أن هذه مشكلة يجب أن يحاول Angular حلها بالضرورة. إنه أكثر من الآثار الجانبية لاستخدام angular-animate مع مكتبات css الأخرى ، والتي قد تحتوي على بعض انتقالات css المضمنة التي لا تتوقعها!

استغرق الأمر وقتًا طويلاً لتعقب السبب الجذري ، ولكن كان من الجيد أن نجد أخيرًا سببًا منطقيًا.

نعم ، هذه مشكلة مهمة مع ngAnimate ، ولكن بسبب عدم التحكم في getComputedStyle وسلسلة الانتقالات في المكتبات الأخرى ، فإن ngAnimate غير قادر على اكتشاف ذلك.

هناك حلان لإصلاح هذا:

1) تجاوز التصميم لفئة .ng-animate :
http://jsfiddle.net/9krLr/27/

السبب في عدم نجاحها من قبل كان بسبب نقص خصوصية CSS.

2) استخدم $animateProvider.classNameFilter(regex) . سيضع regex في هذه الحالة حظرًا صارمًا على جميع الرسوم المتحركة التي تم تشغيلها في ngAnimate ويسمح فقط للرسوم المتحركة بالحدوث إذا كان التعبير العادي يطابق className الموجود في العنصر الذي تريد أن تكون متحركًا.

أوه ، وضع التكوين في موفر طريقة جيدة للذهاب ، أحب ذلك كثيرًا ، @ matatsko!

pnutshellmenace شكرا على الحل السريع. أنقذت يومي.

لا أفهم ما هو الحل النهائي هنا. @ ماتسكو قال:

قد يكون من الأفضل جعل ngAnimate أقل سذاجة ويتم تحريكه فقط عندما يكون متحركًا - هل هناك بادئة CSS في مكان ما

لكني لا أرى أي تطبيق من هذا القبيل. ألقيت نظرة على $animateProvider.classNameFilter(regex) ولكن مرة أخرى ، بقيت لدي أسئلة أكثر من الإجابات. ما هي الطريقة العملية لتنفيذ ذلك وماذا لو كان هناك أكثر من اسم فئة واحد قابل للتطبيق؟

لا أرى أي سبب يجعل ngAnimate يفترض أنني أريد تحريك كل شيء. ستكون هناك دائمًا أشياء لا أرغب في تحريكها ، ولدي حاليًا أشياء لا أرغب في تحريكها بخلاف العكس ، مما يجعل تصميمها يدويًا لتعطيل الانتقالات أمرًا غير جذاب.

تحرير: عثرت على إدخال المدونة هذا الذي يضع الأمور في نصابها ... سأجربها :

تحرير 2: نجحت إضافة $animateProvider.classNameFilter(/enable-animate/); ، لكن في هذه العملية وجدت بعض السلوك المثير للاهتمام:

لقد قمت بتضمين ملف .js لوحدة زاويّة لجهة خارجية كانت تعتمد على ngAnimate ، وبطريقة ما كان ذلك يتسبب في تشغيل الرسوم المتحركة حتى في الوحدة النمطية الخاصة بي. بطريقة ما كان ngAnimate يؤثر على نطاق الوحدة الرئيسية؟

أفضل هذه الإجابة باستخدام $scope.$evalAsync(); للعملية غير المتزامنة. يعمل بشكل جيد.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات