簡體   English   中英

如何立即刪除css過渡?

[英]How to remove css transitions without delay?

我希望順利轉換css屬性然后我想立即更改css屬性值然后我想再次附加轉換。 為了更好地理解,請參閱以下示例:

 if ($(".marquee").height() < $(".marquee-content").outerHeight(true)) { $(".marquee-content").clone().appendTo($(".marquee-wrapper")); } $('.marquee-wrapper').css("transition", "transform 3s linear"); $('.marquee-wrapper').css("transform", "translateY(-" + $(".marquee-content").outerHeight(true) + "px)"); setInterval(function() { $('.marquee-wrapper').css("transition", "none"); $('.marquee-wrapper').css("transform", "translateY(100px)"); //This should Immediately change translateY to 100px without smooth transition. But this doesn't happen without adding a delay before the below written line // Its weird why javascript engine executes the below line before executing this line $('.marquee-wrapper').css("transition", "transform 3s linear"); $('.marquee-wrapper').css("transform", "translateY(-" + $(".marquee-content").outerHeight(true) + "px)"); }, 3000); 
 .marquee { margin: auto; width: 600px; height: 200px; overflow: auto; } .marquee-wrapper { transform: translateY(0); } .marquee-content { margin: 0; padding: 30px 0; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <section class="marquee"> <div class="marquee-wrapper"> <div class="marquee-content"> Updates: Update (8 Mar 2016): Now plugin have new option: startVisible The marquee will be visible in the start if set to true. Thanks to @nuke-ellington ðŸ' Update (24 Jan 2014): Note: people who been asking me how to use this plugin with content being loaded with Ajax, please read notes about this update. New methods added, so now after you start the plugin using var $mq = $('.marquee').marquee();, you start the plugin using var $mq = $('.marquee').marquee();, you start the plugin using var $mq = $('.marquee').marquee();, then you can pause, resume, togglepause, resume) and desestroy destroy toggle(pause, resume) and destroy toggle(pause, resume) and destroy methods eg to remove the marquee plugin from your element simply use $mq.marquee('destroy');. Similarly you can use pause the marquee any time using $mq.marquee('pause');. </div> </div> </section> 

正如您在setInterval中看到的,我首先將轉換設置為none,然后將translateY轉換為100px。 現在原則上這應該突然將div轉換為100px,但這不會發生在將div移動到100px之前javascript引擎執行下一行並重新分配轉換。 在下面的例子中,我在重新分配轉換之前給出了100ms的延遲,它可以工作:

 if ($(".marquee").height() < $(".marquee-content").outerHeight(true)) { $(".marquee-content").clone().appendTo($(".marquee-wrapper")); } $('.marquee-wrapper').css("transition", "transform 3s linear"); $('.marquee-wrapper').css("transform", "translateY(-" + $(".marquee-content").outerHeight(true) + "px)"); setInterval(function() { $('.marquee-wrapper').css("transition", "none"); $('.marquee-wrapper').css("transform", "translateY(100px)"); //This Immedeately change translateY to 100px without smooth transition now setTimeout(function(){ $('.marquee-wrapper').css("transition", "transform 3s linear"); $('.marquee-wrapper').css("transform", "translateY(-" + $(".marquee-content").outerHeight(true) + "px)"); },100); }, 3000); 
 .marquee { margin: auto; width: 600px; height: 200px; overflow: auto; } .marquee-wrapper { transform: translateY(0); } .marquee-content { margin: 0; padding: 30px 0; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <section class="marquee"> <div class="marquee-wrapper"> <div class="marquee-content"> Updates: Update (8 Mar 2016): Now plugin have new option: startVisible The marquee will be visible in the start if set to true. Thanks to @nuke-ellington ðŸ' Update (24 Jan 2014): Note: people who been asking me how to use this plugin with content being loaded with Ajax, please read notes about this update. New methods added, so now after you start the plugin using var $mq = $('.marquee').marquee();, you start the plugin using var $mq = $('.marquee').marquee();, you start the plugin using var $mq = $('.marquee').marquee();, then you can pause, resume, togglepause, resume) and desestroy destroy toggle(pause, resume) and destroy toggle(pause, resume) and destroy methods eg to remove the marquee plugin from your element simply use $mq.marquee('destroy');. Similarly you can use pause the marquee any time using $mq.marquee('pause');. </div> </div> </section> 

我的問題是:

  1. 如何在更改translate屬性之前阻止javscript引擎重新分配transition屬性,沒有任何延遲?
  2. 為什么javscript引擎會在當前行( $('.marquee-wrapper').css("transform", "translateY(100px)");之前的腳本中執行即將到來的行( $('.marquee-wrapper').css("transition", "transform 3s linear"); $('.marquee-wrapper').css("transform", "translateY(100px)");

在單個語句中對transitiontransform CSS屬性進行分組可以得到正確的結果,而不必使用100毫秒的延遲:

$('.marquee-wrapper').css({ transition: "transform 3s linear", transform: "translateY(-" + $(".marquee-content").outerHeight(true) + "px)" });
setInterval(function () {
    $('.marquee-wrapper').css({ transition: "none", transform: "translateY(100px)" });
    $('.marquee-wrapper').css({ transition: "transform 3s linear", transform: "translateY(-" + $(".marquee-content").outerHeight(true) + "px)" });
}, 3000);

 if ($(".marquee").height() < $(".marquee-content").outerHeight(true)) { $(".marquee-content").clone().appendTo($(".marquee-wrapper")); } $('.marquee-wrapper').css({ transition: "transform 3s linear", transform: "translateY(-" + $(".marquee-content").outerHeight(true) + "px)" }); setInterval(function () { $('.marquee-wrapper').css({ transition: "none", transform: "translateY(100px)" }); $('.marquee-wrapper').css({ transition: "transform 3s linear", transform: "translateY(-" + $(".marquee-content").outerHeight(true) + "px)" }); }, 3000); 
 .marquee { margin: auto; width: 600px; height: 200px; overflow: auto; } .marquee-wrapper { transform: translateY(0); } .marquee-content { margin: 0; padding: 30px 0; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <section class="marquee"> <div class="marquee-wrapper"> <div class="marquee-content"> Updates: Update (8 Mar 2016): Now plugin have new option: startVisible The marquee will be visible in the start if set to true. Thanks to @nuke-ellington ðŸ' Update (24 Jan 2014): Note: people who been asking me how to use this plugin with content being loaded with Ajax, please read notes about this update. New methods added, so now after you start the plugin using var $mq = $('.marquee').marquee();, you start the plugin using var $mq = $('.marquee').marquee();, you start the plugin using var $mq = $('.marquee').marquee();, then you can pause, resume, togglepause, resume) and desestroy destroy toggle(pause, resume) and destroy toggle(pause, resume) and destroy methods eg to remove the marquee plugin from your element simply use $mq.marquee('destroy');. Similarly you can use pause the marquee any time using $mq.marquee('pause');. </div> </div> </section> 


這種行為的原因可能是,設置兩個CSS屬性會立即觸發立即重新繪制頁面,而單獨設置它們則不會。

已知一些Javascript命令會導致重繪。 獲取元素的offsetHeight是最經常提到的(見本文 )。 事實上,在本文中使用它來解決CSS轉換的問題與此處介紹的問題非常類似。 如果我們通過獲取轉換之間的元素高度來測試該方法,我們會看到結果行為確實是正確的:

$('.marquee-wrapper').css("transition", "none");
$('.marquee-wrapper').css("transform", "translateY(100px)");
$('.marquee-wrapper').height(); // Force a repaint
$('.marquee-wrapper').css("transition", "transform 3s linear");
$('.marquee-wrapper').css("transform", "translateY(-" + $(".marquee-content").outerHeight(true) + "px)");

 if ($(".marquee").height() < $(".marquee-content").outerHeight(true)) { $(".marquee-content").clone().appendTo($(".marquee-wrapper")); } $('.marquee-wrapper').css("transition", "transform 3s linear"); $('.marquee-wrapper').css("transform", "translateY(-" + $(".marquee-content").outerHeight(true) + "px)"); setInterval(function () { $('.marquee-wrapper').css("transition", "none"); $('.marquee-wrapper').css("transform", "translateY(100px)"); $('.marquee-wrapper').height(); // Force a repaint $('.marquee-wrapper').css("transition", "transform 3s linear"); $('.marquee-wrapper').css("transform", "translateY(-" + $(".marquee-content").outerHeight(true) + "px)"); }, 3000); 
 .marquee { margin: auto; width: 600px; height: 200px; overflow: auto; } .marquee-wrapper { transform: translateY(0); } .marquee-content { margin: 0; padding: 30px 0; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <section class="marquee"> <div class="marquee-wrapper"> <div class="marquee-content"> Updates: Update (8 Mar 2016): Now plugin have new option: startVisible The marquee will be visible in the start if set to true. Thanks to @nuke-ellington ðŸ' Update (24 Jan 2014): Note: people who been asking me how to use this plugin with content being loaded with Ajax, please read notes about this update. New methods added, so now after you start the plugin using var $mq = $('.marquee').marquee();, you start the plugin using var $mq = $('.marquee').marquee();, you start the plugin using var $mq = $('.marquee').marquee();, then you can pause, resume, togglepause, resume) and desestroy destroy toggle(pause, resume) and destroy toggle(pause, resume) and destroy methods eg to remove the marquee plugin from your element simply use $mq.marquee('destroy');. Similarly you can use pause the marquee any time using $mq.marquee('pause');. </div> </div> </section> 

我會解釋你為什么會這樣。
我一直在處理javascript動畫,並且有許多js庫(專注於數學),考慮到操作延遲(I / O可用性策略)和超時。

在您的第一個代碼段中,您有以下操作:

$('.marquee-wrapper').css("transform", "translateY(100px)");
$('.marquee-wrapper').css("transition", "transform 3s linear");

轉變

Css變換方法使用具有高計算成本的基於矩陣的運算。 有一些css動畫框架使用圖形處理器單元(具有矩陣運算符),其工作速度快幾倍,以實現平滑,實時的圖形操作。

過渡

Css Transition是另一種圖形操作,但不會使用純[matrix op matrix]變換修改css實體,它使用正確的1維運算符,這意味着您的css矩陣使用[matrix op array]

然后選擇線性模式,在元素的位置上應用線性插值(可能只是幾個積分運算符)。 它具有較低的計算成本,這使得整個轉換操作的計算速度更快。

這是在某種時間軸中執行的執行模式:

transform         calculation-process
exec -----------------------------------------> applied
 |         |                            |        |
 |         |                            |        |
 |         |                            |        |
transition |     calculation-process    |        |
--------- exec ---------------------> applied --------- 

由於javascript頂部的jQuery具有非阻塞代碼執行(對於i / o依賴函數,除非你編碼同步),這是javascript異步策略的基礎,允許在先前完成之前執行下一個操作。

使用超時功能進行修復可確保在運行以下代碼之前完成轉換操作,但作為限制,它適用於計算速度與當前客戶端處理器相似的客戶端。 (如果你在電腦上開發它,那么智能手機可能會失敗)

我在代碼中使用的另一個解決方案是使用jquery回調。 看一下jquery animate() doc ,其中顯示了:

.animate(properties [,duration] [,easing] [,complete])

在您的示例中,它將類似於:

$('.marquee-wrapper').animate({"transform": "translateY(100px)"}, function(){
    // this code runs after transform ends...
    $('.marquee-wrapper').css("transition", "transform 3s linear");
    $('.marquee-wrapper').css("transform", "translateY(-" + $(".marquee-content").outerHeight(true) + "px)");
});

我找到了很多有用的庫,可以“認真地”使用動畫。 這些是我使用的一些庫:

d3.js
bounce.js
secuence.js
paper.js

我希望它有所幫助。

更新
關於動畫和css過渡在這里有一個很好的答案。

我認為這里有一些很好的答案告訴你它為什么會起作用,但是如果你想要一個更多瀏覽器支持的動畫,請使用jQuery animations

$wrap = $(".marquee-wrapper")
$con = $(".marquee-content");
cHeight = $con.outerHeight(true)

if ($(".marquee").height() < cHeight) {
  $con.clone().appendTo( $wrap );
}

function animate() {
  $wrap.animate({
    top: "-=" + cHeight
  }, 3000, "linear", function() { 
    $(this).css("top", "0");
    animate();
  });
}

animate();

 //Cache values $wrap = $(".marquee-wrapper") $con = $(".marquee-content"); cHeight = $con.outerHeight(true) if ($(".marquee").height() < cHeight) { $con.clone().appendTo( $wrap ); } function animate() { $wrap.animate({ top: "-=" + cHeight //minus height from the value of top }, 3000, // milisecs of animations length "linear", // type of animations function() { //function to run after animation is complete $(this).css("top", "0"); animate(); }); } animate(); //Run function in the beginning 
 .marquee { margin: auto; width: 600px; height: 200px; overflow: auto; position: relative; } .marquee-wrapper { position: absolute; } .marquee-content { margin: 0; padding: 30px 0; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <section class="marquee"> <div class="marquee-wrapper"> <div class="marquee-content"> Updates: Update (8 Mar 2016): Now plugin have new option: startVisible The marquee will be visible in the start if set to true. Thanks to @nuke-ellington ðŸ' Update (24 Jan 2014): Note: people who been asking me how to use this plugin with content being loaded with Ajax, please read notes about this update. New methods added, so now after you start the plugin using var $mq = $('.marquee').marquee();, you start the plugin using var $mq = $('.marquee').marquee();, you start the plugin using var $mq = $('.marquee').marquee();, then you can pause, resume, togglepause, resume) and desestroy destroy toggle(pause, resume) and destroy toggle(pause, resume) and destroy methods eg to remove the marquee plugin from your element simply use $mq.marquee('destroy');. Similarly you can use pause the marquee any time using $mq.marquee('pause');. </div> </div> </section> 

的jsfiddle

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM