如何按顺序应用CSS更改?

时间:2016-08-09 18:02:23

标签: javascript css css-transitions

我有时遇到过我想立即对CSS进行多项更改的情况,确保每个更改都由渲染器注册。

Here's a simplified example

元素的高度是自动的,因此无法从中转换。所以我想将元素高度设置为当前计算高度,然后立即更改类以开始转换。如果在下一行代码中发生这种情况,则css-renderer没有时间对第一个更改作出反应,就好像只更改了类 - >没有过渡。

var foo = $(".foo");
foo[0].addEventListener("click", function(ev){
  foo.css({"height":foo.height()+"px"});
  foo.addClass("active");
});  //this doesn't work, foo.css…' is ignored.

我们可以使用window.requestAnimationFrame()延迟到最小的动画时间步长,但是,由于浏览器不同,这些已经需要两个嵌套调用来支持Firefox。

var dan = $(".dan");
dan[0].addEventListener("click", function(ev){
  window.requestAnimationFrame(function(){
    dan.css({"height":dan.height()+"px"});
    window.requestAnimationFrame(function(){
      dan.addClass("active");
    });
  });
});  //this does work (afai can tell), but feels overdone with all that nesting.

从技术上讲,此代码有效。我只是想知道这是否真的是链接css更改的最佳方式,或者是否有其他方法。

2 个答案:

答案 0 :(得分:1)

您可以在此处使用<div class="menu-item"><a href='javascript:heywoodEnvelopes()' id="ww">Heywood White Wove</a></div> <div class="menu-item"><a href='javascript:heywoodMI()' id="mi">Heywood White Wove MI</a></div> <div class="menu-item"><a href='javascript:heywoodRemittance()' id="re">Heywood Remittance</a></div> <div class="menu-item"><a href="javascript:heywoodBC()" id="bc">Heywood Booklets &amp; Catalogs</a></div> <span class="download-link">If your browser does not support viewing PDF's, please click<a class="download" href="#" id="pdfLink" download> HERE </a>to download a copy.</span>,以确保在计算setTimeout的{​​{1}}后始终更改班级。

示例:

&#13;
&#13;
height
&#13;
div
&#13;
var foo = document.getElementsByClassName('foo')[0];
var bar = document.getElementsByClassName('bar')[0];
var dan = document.getElementsByClassName('dan')[0];

function fooFunction(element) {
    element.style.height = element.clientHeight + 'px';

    setTimeout(function(){
        element.classList.add('active');
        element.removeAttribute('style');
    },10);

}

foo.addEventListener('click',function(){fooFunction(foo);},false);
bar.addEventListener('click',function(){fooFunction(bar);},false);
dan.addEventListener('click',function(){fooFunction(dan);},false);
&#13;
&#13;
&#13;

答案 1 :(得分:-1)

如果在click事件之前不知道目标元素的高度,只需在DOM准备好后检查它,并将每个目标元素设置为它自己的高度。 这样,当你点击目标元素时: *动画将起作用,因为元素的高度已经设置。 *在点击事件上执行的命令会少一个。

如果你已经使用jQuery,你可以一直使用它:

$(document).ready(function(){ // use document ready so we can get the target elements height after they finished to load. 
    var $tran = $('.transition'); // get "transition" class. instead of using different class name for each element, i use unique class for the animation part, the change needs to be on the HTML and CSS too of course, you will see it in the example. 
    $tran.each(function(){ // run each loop so we can get each of the elements that have the class "transition", this is important when the elements height different from each other.
        var height = $(this).height(); // get the height of the current element in the loop. 
        $(this).height(height); // set the height of the current element in the loop. 
    });
    $tran.click(function(){ // set jQuery click event
        $(this).addClass('active'); // add the "active" class
    });
});

香草:

document.addEventListener('DOMContentLoaded', function(){ // use DOMContentLoaded so we can get the target elements height after they finished to load.
  var tran = document.getElementsByClassName('transition'); // get "transition" class.
  for ( let i = 0; i <= tran.length-1; i++ ){ // run for loop so we can get each of the elements that have the class "transition", this is important when the elements height different from each other.
    let height = tran[i].clientHeight; // get the height of the current element in the loop. 
    tran[i].style.height = height + 'px'; // set the height of the current element in the loop. 
    tran[i].addEventListener("click", function(ev){ // set click event
      this.className = this.className + " active"; // add the "active" class 
    });
  }
});

每个目标元素都获得了过渡类:

<div class="foo transition">
...
<div class="bar transition">
...  
<div class="dan transition">
... 

转换部分移动到它自己的类中,因此如果您决定删除它或将其用于其他元素,您可以稍后从HTML中删除该类。 它不再位于“活动”类中,因此它会影响元素而不会与click事件相关联,这样您就可以使用toggleClass()而不是addClass()来实现“开放” “再次点击元素时动画:

.foo, .bar, .dan {
  width: 20%;
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
}
.transition {
  -webkit-transition: height 1000ms;
  transition: height 1000ms;
}
.active {
  height: 50px !important;
}

直播示例: https://jsfiddle.net/84joouov/ *在示例中,我允许您通过将“use_jquery”变量设置为true或false来选择使用纯JS到jQuery。