CSS संक्रमण प्रभावों को अस्थायी रूप से अक्षम करने का सबसे साफ तरीका क्या है?


209

मेरे पास कुछ प्रभाव वाले कुछ / सभी लागू किए गए डोम तत्व हैं:

#elem {
  -webkit-transition: height 0.4s ease;
  -moz-transition: height 0.4s ease;
  -o-transition: height 0.4s ease;
  transition: height 0.4s ease;
}

मैं एक jQuery प्लगइन लिख रहा हूं जो इस तत्व का आकार बदल रहा है, मुझे इन प्रभावों को अस्थायी रूप से अक्षम करने की आवश्यकता है ताकि मैं इसे आसानी से आकार दे सकूं।

इन प्रभावों को अस्थायी रूप से अक्षम करने का सबसे सुंदर तरीका क्या है (और फिर उन्हें फिर से सक्षम करना), बशर्ते वे माता-पिता से लागू हो सकते हैं या बिल्कुल भी लागू नहीं हो सकते हैं।


1
यह आशाजनक लगता है: ricostacruz.com/jquery.transit । यह एमआईटी लाइसेंस प्राप्त है, इसलिए आप इसे शामिल कर सकते हैं, या इसका अध्ययन कर सकते हैं कि वह कैसे करता है।
रॉबर्ट हार्वे

सभी उत्तर एक वर्ग जोड़ते हैं.notransition । इसे दूसरे तरीके से करना अधिक उचित होगा, यानी #elem.yestransitionअपने सीएसएस के साथ लक्षित करें और इस वर्ग को हटा दें। यह *आपके सीएसएस में बुरा s को हटाता है ।
मार्सलोथेकेन

जवाबों:


484

संक्षिप्त जवाब

इस सीएसएस का प्रयोग करें:

.notransition {
  -webkit-transition: none !important;
  -moz-transition: none !important;
  -o-transition: none !important;
  transition: none !important;
}

इसके अलावा या तो जेएस (jQuery के बिना) ...

someElement.classList.add('notransition'); // Disable transitions
doWhateverCssChangesYouWant(someElement);
someElement.offsetHeight; // Trigger a reflow, flushing the CSS changes
someElement.classList.remove('notransition'); // Re-enable transitions

या jQuery के साथ यह जेएस ...

$someElement.addClass('notransition'); // Disable transitions
doWhateverCssChangesYouWant($someElement);
$someElement[0].offsetHeight; // Trigger a reflow, flushing the CSS changes
$someElement.removeClass('notransition'); // Re-enable transitions

... या आपके द्वारा काम कर रहे अन्य पुस्तकालय या ढांचे का उपयोग करके समान कोड।

व्याख्या

यह वास्तव में एक काफी सूक्ष्म समस्या है।

सबसे पहले, आप शायद एक 'नोटरीशन' क्लास बनाना चाहते हैं जिसे आप अपने *-transitionसीएसएस विशेषताओं को सेट करने के लिए तत्वों पर लागू कर सकते हैं none। उदाहरण के लिए:

.notransition {
  -webkit-transition: none !important;
  -moz-transition: none !important;
  -o-transition: none !important;
  transition: none !important;
}

(माइनर अलग - टिप्पणी एक की कमी -ms-transition। में वहाँ आप इसकी आवश्यकता नहीं है पहले इंटरनेट एक्सप्लोरर के समर्थन बदलाव करने के लिए संस्करण। सब पर आईई 10 था जो समर्थित उन्हें बिना उपसर्ग,।)

लेकिन यह सिर्फ शैली है, और आसान सा है। जब आप इस वर्ग का उपयोग करने का प्रयास करते हैं, तो आप एक जाल में दौड़ेंगे। जाल यह है कि कोड इस तरह काम नहीं करेगा जिस तरह से आप उम्मीद कर सकते हैं:

// Don't do things this way! It doesn't work!
someElement.classList.add('notransition')
someElement.style.height = '50px' // just an example; could be any CSS change
someElement.classList.remove('notransition')

स्वाभाविक रूप से, आप सोच सकते हैं कि ऊंचाई में परिवर्तन एनिमेटेड नहीं होगा, क्योंकि यह तब होता है जब 'नोट्रिशन' वर्ग लागू होता है। वास्तविकता में, हालांकि, यह होगा एनिमेटेड , कम से कम सभी आधुनिक ब्राउज़रों में मैंने कोशिश की है। समस्या यह है कि ब्राउज़र स्टाइल परिवर्तनों को कैशिंग कर रहा है, जो कि जावास्क्रिप्ट को निष्पादित करने तक पूरा करने की आवश्यकता है, और फिर सभी परिवर्तनों को एक एकल रिफ्लो में बना रहा है। नतीजतन, यह एक रीफ़्लो करता है, जहाँ कोई परिवर्तन नहीं किया जाता है या परिवर्तन सक्षम होते हैं या नहीं, लेकिन ऊँचाई में शुद्ध परिवर्तन होता है। नतीजतन, यह ऊंचाई में बदलाव को दर्शाता है।

आप एक उचित और साफ तरीका सोच सकते हैं कि इस तरह से 1ms के समय में 'नोट्रिशन' वर्ग को हटाने के लिए इस तरह से लपेटना होगा:

// Don't do things this way! It STILL doesn't work!
someElement.classList.add('notransition')
someElement.style.height = '50px' // just an example; could be any CSS change
setTimeout(function () {someElement.classList.remove('notransition')}, 1);

लेकिन यह मज़बूती से काम नहीं करता है। मैं WebKit ब्राउज़रों में उपरोक्त कोड विराम नहीं बना पा रहा था, लेकिन फ़ायरफ़ॉक्स (धीमी और तेज़ दोनों मशीनों पर) आप कभी-कभी (बेतरतीब ढंग से) भोले दृष्टिकोण का उपयोग करने के समान व्यवहार प्राप्त कर सकते हैं। मुझे लगता है कि इसका कारण यह है कि जावास्क्रिप्ट निष्पादन के लिए यह काफी संभव है कि टाइमआउट फ़ंक्शन ब्राउज़र निष्क्रिय होने के समय तक निष्पादित होने की प्रतीक्षा कर रहा है और अन्यथा अवसरवादी रिफ्लेक्स करने के बारे में सोच रहा होगा, और यदि ऐसा होता है, तो फ़ायरफ़ॉक्स reflow से पहले पंक्तिबद्ध फ़ंक्शन को निष्पादित करता है।

समस्या का एकमात्र समाधान मैंने पाया है कि 'नोटरीन्स' कक्षा को हटाने से पहले, तत्व में परिवर्तन को सीएसएस में फेरबदल करने के लिए मजबूर किया जाता है। ऐसा करने के विभिन्न तरीके हैं - कुछ के लिए यहां देखें । करीबी बात यह है कि ऐसा करने का एक 'मानक' तरीका offsetHeightहै, तत्व की संपत्ति को पढ़ना ।

एक समाधान जो वास्तव में काम करता है, वह है

someElement.classList.add('notransition'); // Disable transitions
doWhateverCssChangesYouWant(someElement);
someElement.offsetHeight; // Trigger a reflow, flushing the CSS changes
someElement.classList.remove('notransition'); // Re-enable transitions

यहाँ एक जेएस फिडेल है जो मेरे द्वारा वर्णित तीन संभावित दृष्टिकोणों को दिखाता है (दोनों एक सफल दृष्टिकोण और दो असफल व्यक्ति): http://jsfiddle.net/2uVAA/131/


8
एक्सेलेंटे उत्तर। अच्छी नौकरी, और सराहना की जब से मैं एक ही समस्या के साथ आया था। क्या होगा यदि मैं केवल एक प्रकार के संक्रमण को दूर करना चाहता हूं?
राफेलमोराइसिस

2
आपका समाधान सही है, लेकिन अधिक पृष्ठभूमि जानकारी की तलाश करने वालों के लिए: stackoverflow.com/a/31862081/1026
निकोलय

2
एक तरफ मामूली नाबालिग, IE10 उपसर्गों के साथ जहाज करने के लिए IE का पहला स्थिर संस्करण था । रिलीज़-प्रीव्यू को छोड़कर पूर्व-रिलीज़ संस्करण, आवश्यक चीजों के एक समूह के साथ -ms-संक्रमण के लिए उपसर्ग आवश्यक है। मुझे संदेह है कि, इसका एक कारण है -ms- उपसर्ग आज दिखाई देता है। अन्य, बहुत अधिक संभावना है, कारण सामान्य कार्गो पंथ है जिसे हम सभी जानते हैं और विक्रेता उपसर्गों के बारे में प्यार करते हैं।
BoltClock

1
दिलचस्प है कि बस एक तत्व की ऑफसेट ऊंचाई की जाँच एक reflow चलाता है। काश मैं एक साल पहले यह जानता था जब मैं इसी समस्या के साथ दीवार के खिलाफ अपना सिर पीट रहा था। क्या यह अभी भी इसे संभालने का सबसे आदर्श तरीका माना जाता है?
Brett84c

2
एसवीजी तत्वों को ऑफसेट करने के लिए रिफ्लो चाल काम नहीं करती है, जिसमें एक ऑफसेटहाइट विशेषता नहीं होती है; setTimout काम करता है।
piotr_cz

19

मैं DaneSoul द्वारा सुझाए गए एनीमेशन को अक्षम करने की वकालत करूंगा, लेकिन स्विच को वैश्विक बनाने के लिए:

/*kill the transitions on any descendant elements of .notransition*/
.notransition * { 
  -webkit-transition: none !important; 
  -moz-transition: none !important; 
  -o-transition: none !important; 
  -ms-transition: none !important; 
  transition: none !important; 
} 

.notransitionतब bodyतत्व पर लागू किया जा सकता है , प्रभावी रूप से पृष्ठ पर किसी भी संक्रमण एनीमेशन को ओवरराइड कर सकता है :

$('body').toggleClass('notransition');

2
वास्तव में यह सही विकल्प imo है। विशेष रूप से * बहुत मदद करता है, यह सुनिश्चित करते हुए कि कोई भी उप एनिमेशन ट्रिगर नहीं होता है। धन्यवाद, उत्थान किया।
स्किज़डॉकी

यह उन स्थितियों के लिए सही उत्तर है जहां आप बस एक ही बार में करना चाहते हैं। उदाहरण के लिए, मैं मोबाइल पर घूमते समय संक्रमण को अक्षम करना चाहता हूं और यह उसके लिए एकदम सही है।
बेन लछमन

मैं कुछ जटिल परिदृश्य में, कोणीयज में इसका उपयोग कर रहा था, लेकिन भगवान द्वारा यह मेरे सिर को पीटने के दिनों के बाद इतना मददगार था।
आदित्य सांसद

2
प्रदर्शन के लिहाज से मैं यह उम्मीद नहीं कर सकता कि यह एक अच्छा विचार है। "ओह, बस इसे पृष्ठ पर हर जगह लागू करें, जो चीजों को आसान बनाता है!"
Lodewijk

1
शायद पूरी तरह से प्रभावी होने के लिए ".प्रोट्रांसिशन" और ".प्रोटांसिशन *" दोनों का चयन करना चाहिए।
नाथन

19

अतिरिक्त सीएसएस वर्ग जोड़ें जो संक्रमण को रोकता है, और फिर इसे पिछली स्थिति में वापस लाने के लिए हटा दें। यह CSS और JQuery कोड दोनों को छोटा, सरल और अच्छी तरह से समझने योग्य बनाता है।

सीएसएस :

.notransition {
  -webkit-transition: none !important;
  -moz-transition: none !important;
  -o-transition: none !important;
  -ms-transition: none !important;
  transition: none !important;
}

!important यह सुनिश्चित करने के लिए जोड़ा गया कि इस नियम में अधिक "वजन" होगा, क्योंकि आईडी सामान्य रूप से वर्ग की तुलना में अधिक विशिष्ट है।

JQuery :

$('#elem').addClass('notransition'); // to remove transition
$('#elem').removeClass('notransition'); // to return to previouse transition

5
-1 क्योंकि यह क्रोम या फ़ायरफ़ॉक्स में मेरे लिए समस्या को हल करने के लिए पर्याप्त नहीं था - अगर मेरे पास जावास्क्रिप्ट है जो क्लास को जोड़ता है, परिवर्तन करता है, और क्लास को हटा देता है, कभी-कभी परिवर्तन अभी भी चेतन करते हैं। मैंने अंतिम घंटे या दो को इस समस्या को कुछ विस्तार से पढ़ा है और बाद में उत्तर दिखाएगा जिसमें उन मामलों को दिखाया जाएगा जहां भोली दृष्टिकोण विफल रहता है, साथ ही एक साफ-सुथरी हैक जो समाधान को ठीक करने के लिए यहां एक मजबूर करता है जो परिवर्तनों को करने और हटाने के बीच में एक reflow मजबूर करता है 'नोटबंदी' वर्ग।
मार्क एमी

9

शुद्ध जेएस समाधान (कोई सीएसएस कक्षाएं) के लिए, बस करने के transitionलिए सेट करें 'none'। CSS में निर्दिष्ट संक्रमण को पुनर्स्थापित करने के लिए, transitionएक खाली स्ट्रिंग पर सेट करें ।

// Remove the transition
elem.style.transition = 'none';

// Restore the transition
elem.style.transition = '';

यदि आप विक्रेता उपसर्गों का उपयोग कर रहे हैं, तो आपको उन्हें भी सेट करना होगा।

elem.style.webkitTransition = 'none'

8

आप इस सीएसएस कोड के साथ पृष्ठ के सभी तत्वों के लिए एनीमेशन, संक्रमण, ट्रैसफॉर्म को अक्षम कर सकते हैं

var style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = '* {' +
'/*CSS transitions*/' +
' -o-transition-property: none !important;' +
' -moz-transition-property: none !important;' +
' -ms-transition-property: none !important;' +
' -webkit-transition-property: none !important;' +
'  transition-property: none !important;' +
'/*CSS transforms*/' +
'  -o-transform: none !important;' +
' -moz-transform: none !important;' +
'   -ms-transform: none !important;' +
'  -webkit-transform: none !important;' +
'   transform: none !important;' +
'  /*CSS animations*/' +
'   -webkit-animation: none !important;' +
'   -moz-animation: none !important;' +
'   -o-animation: none !important;' +
'   -ms-animation: none !important;' +
'   animation: none !important;}';
   document.getElementsByTagName('head')[0].appendChild(style);

1
सबसे पहले यह भयानक है, धन्यवाद! दूसरी बात यह भी है कि कुछ अन्य संपत्तियों को भी स्थापित किया जाना चाहिए; देखें github.com/japgolly/test-state/blob/master/util/sared/src/test/…
Golly

@ अन्य वे गुण अंतिम डिजाइन को प्रभावित कर सकते हैं
जोंपरल

0

मुझे लगता है कि आप एक अलग सीएसएस क्लास बना सकते हैं जिसे आप इन मामलों में उपयोग कर सकते हैं:

.disable-transition {
  -webkit-transition: none;
  -moz-transition: none;
  -o-transition: color 0 ease-in;
  -ms-transition: none;
  transition: none;
}

फिर jQuery में आप कक्षा को इस तरह टॉगल करेंगे:

$('#<your-element>').addClass('disable-transition');

हां मुझे लगता है कि यह सबसे अच्छा तरीका है, वास्तव में प्लगइन उस सीएसएस ब्लॉक को पेज में इंजेक्ट कर सकता है
सैम केसर

3
क्या आप सुनिश्चित हैं कि महत्वपूर्ण वर्ग शासक आईडी को ओवरराइड करेगा?
डेनसूल

0

यदि आप सभी संक्रमणों को रोकने के लिए एक सरल no-jquery समाधान चाहते हैं:

  1. इस सीएसएस जोड़ें:
body.no-transition * {
  transition: none !important;
}
  1. और फिर अपने जेएस में:
document.body.classList.add("no-transition");

// do your work, and then either immediately remove the class:

document.body.classList.remove("no-transition");

// or, if browser rendering takes longer and you need to wait until a paint or two:

setTimeout(() => document.body.classList.remove("no-transition"), 1);

// (try changing 1 to a larger value if the transition is still applying)

-1

यदि आप CSS बदलावों, परिवर्तनों और एनिमेशन को वर्तमान वेबपेज से हटाना चाहते हैं तो आप बस इस छोटी सी स्क्रिप्ट को निष्पादित कर सकते हैं जिसे मैंने लिखा था (आपके ब्राउज़र कंसोल के अंदर):

let filePath = "https://dl.dropboxusercontent.com/s/ep1nzckmvgjq7jr/remove_transitions_from_page.css";
let html = `<link rel="stylesheet" type="text/css" href="${filePath}">`;
document.querySelector("html > head").insertAdjacentHTML("beforeend", html);

इस css- फाइल को लोड करने के लिए यह वैनिलाजस का उपयोग करता है । यदि आप स्क्रैपर (रूबी-सेलेनियम) के संदर्भ में इसका उपयोग करना चाहते हैं, तो हेयस भी एक गितुब रेपो है: हटाने-सीएसएस-एनिमेशन-रेपो


-3

कर देता है

$('#elem').css('-webkit-transition','none !important'); 

अपने जे एस में इसे मार?

स्पष्ट रूप से प्रत्येक के लिए दोहराएं।


1
फिर आपको इस तथ्य के बाद इसे रीसेट करने की आवश्यकता है, इसलिए आपको इसे संग्रहीत करने की आवश्यकता है, जो बॉयलर प्लेट की एक उचित मात्रा में ले जाएगा
सैम केसर

-4

मैं आपके सीएसएस में इस तरह एक वर्ग होगा:

.no-transition { 
  -webkit-transition: none;
  -moz-transition: none;
  -o-transition: none;
  -ms-transition: none;
  transition: none;
}

और फिर आपके jQuery में:

$('#elem').addClass('no-transition'); //will disable it
$('#elem').removeClass('no-transition'); //will enable it

1
क्या आप सुनिश्चित हैं कि महत्वपूर्ण वर्ग शासक आईडी को ओवरराइड करेगा?
डेनसूल

1
हां, ऐसा इसलिए होगा क्योंकि अब आप # elem.no- संक्रमण को लक्षित कर रहे हैं जो केवल आईडी से अधिक विशिष्ट है
मोईन

3
@MoinZaman Erm, लेकिन आपने अपने CSS में लक्षित नहीं#elem.no-transition किया है, आपने अभी-अभी लक्ष्य किया है .no-transition। शायद आप #elem.no-transitionअपने सीएसएस में लिखने का मतलब ?
मार्क अमेरी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.