CSS转换在jQuery .load回调失败 [英] CSS Transition fails on jQuery .load callback

查看:159
本文介绍了CSS转换在jQuery .load回调失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个函数将html加载到一个jQuery表的表,然后添加一个类到回调的行。该函数由页面上的各种UI驱动事件触发。我也有一个css转换规则,所以颜色应淡入( transition:background-color 1000ms linear )。该函数如下所示:

  function load_tbody(row_id){
$(' tbody')。load(load_tbody.php,function(){
$(row_id).addClass('green');
});
}

加载html后,类成功添加并设置行颜色到绿色。



当我添加一个轻微的延迟,甚至10ms,它工作正常:

  function load_tbody(row_id){
$('tbody')。load(load_tbody.php,function
setTimeout(function(){
$(row_id).addClass('green');
},10);
}
}

.load() 的jQuery文件状态:


如果提供了完整回调,则在执行
后处理和HTML插入后执行。


对我来说,这意味着新元素已经加载到dom中,并且已经应用​​了现有样式,并且已准备好进行操作。为什么转换在第一个示例中失败,但在第二个示例中成功?



这是一个功能完整的示例页面,用于演示有问题的行为:



http://so-37035335.dev。 zuma-design.com/



虽然上面的示例链接来自cdn的jQuery版本2.2.3,但实际页面使用的是1.7版本。 1。在两个版本中都可以看到相同的行为。



UPDATE:



考虑到下面提供的一些意见和答案,我偶然发现了一些更令人困惑的东西。 User @ gdyrrahitis提出了一个建议,让我这样做:

  function tbody_fade(row_id){
$(' tbody')。load(load_tbody.php,function(){
$('tbody')。fadeIn(0,function(){
$(this).find(row_id).addClass ('green');
});
});
}

fadeIn code>回调工作,即使持续时间为0ms。所以这让我想知道...如果元素是理论上有什么背景颜色浏览器认为它在添加该类之前。所以我记录 background-color

  console.log (row_id).css('background-color')); 

你知道吗?只要得到背景色的颜色使一切工作:

  function tbody_get_style(row_id){
$('tbody' ).load(load_tbody.php,function(){
$(row_id).css('background-color');
$(row_id).addClass('green');
});
}

只需添加 $(row_id).css ('background-color'); 似乎什么也不做,导致过渡效果工作。这是一个演示:



http://so-37035335-b.dev.zuma-design.com/



我只是被这个。为什么这个工作?它只是添加一个小的延迟或jQuery获取css属性不知何故对新添加的元素的状态有实质性的影响。

解决方案

添加元素时,需要回流。这同样适用于添加类。但是,当你在单个javascript回合中做这两个时,浏览器就有机会优化第一个。在这种情况下,只有单个(同时是初始和最终)样式值,因此不会发生转换。



setTimeout技巧是有效的,因为它将类添加延迟到另一个javascript回合,因此有两个值呈现给呈现引擎,需要计算,因为有时间点,当第一个呈现给用户时。



批处理规则还有另一个例外。浏览器需要计算立即值,如果你试图访问它。这些值之一是offsetWidth。当您访问它时,触发回流。另一个在实际显示期间单独完成。同样,我们有两个不同的样式值,所以我们可以及时插入它们。



这是真的很少的场合,当这种行为是可取的。大多数时间访问DOM修改之间的回流引起的属性可能导致严重的减速。



首选解决方案可能因人而异,但对我来说,访问of offsetWidth(或getComputedStyle())是最好的。有一些情况下,当setTimeout被触发之间没有样式重新计算。这是罕见的情况,大多在加载的网站,但它发生。然后你不会得到你的动画。通过访问任何计算的样式,您将强制浏览器实际计算它。



在附加元素上触发CSS转换



说明最后一部分



.css()方法是从第一个匹配元素获取样式属性的一种方便方法,特别是根据浏览器访问大多数这些属性的不同方式(基于标准的浏览器中的getComputedStyle()方法,



在某种程度上.css()是jquery等价于javascript function

code> getComputedStyle()
这解释了为什么在添加类之前添加css属性使一切工作



Jquery .css()文档

  //不是animatevar $ a = $('< div>').addClass('box a').appendTo('#wrapper'); $ a.css('opacity'); $ a.addClass('in'); //检查它不只是jQuery //不是animatevar e = document.createElement('div'); e.className ='box e'; document.getElementById('wrapper') .appendChild(e); window.getComputedStyle(e).opacity; e.className + ='in';  

  .box {opacity:0; -webkit-transition:all 2s; -moz-transition:all 2s; transition:all 2s; background-color:red; height:100px; width:100px; margin:10px;}。box.in {opacity:1;}  

 < script src =https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js>< / script>< div id =wrapper < / div> 



这里是列出的工作围绕[SO问题]

新元素的CSS转换[SO Question]


I have a function that loads html into a table with jQuery and subsequently adds a class to one of the rows with the callback. The function is triggered by various UI driven events on the page. I also have a css transition rule so the color should fade in (transition: background-color 1000ms linear). The function looks like this:

function load_tbody(row_id) {
    $('tbody').load("load_tbody.php", function() {
        $(row_id).addClass('green');
    });
}

Once the html is loaded, the class successfully gets added and row color is set to green. However, my css transition rule seems to be ignored.

When I add a slight delay, even 10ms, it works fine:

function load_tbody(row_id) {
    $('tbody').load("load_tbody.php", function() {
        setTimeout(function() {
            $(row_id).addClass('green');
        }, 10);
    });
}

The jQuery docs for .load() state:

If a "complete" callback is provided, it is executed after post-processing and HTML insertion has been performed.

To me this would indicate the the new elements have been loaded into the dom with existing styles applied and are ready for manipulation. Why does the transition fail in the first example but succeed in the second?

Here is a fully functional example page to demonstrate the behaviour in question:

http://so-37035335.dev.zuma-design.com/

While the example above links jQuery version 2.2.3 from cdn, actual page in question uses version 1.7.1. The same behavior can be observed across both versions.

UPDATE:

After considering some of the comments and answers offered below, I've stumbled upon something altogether more confusing. User @gdyrrahitis made a suggestion which lead me to do this:

function tbody_fade(row_id) {
    $('tbody').load("load_tbody.php", function() {
        $('tbody').fadeIn(0, function() {
          $(this).find(row_id).addClass('green');
        });
    });
}

Adding the class inside the fadeIn() callback works, even with a duration of 0ms. So this had me wondering... if the element is theoretically there anyway, what background color does the browser think it has before I add that class. So I log the background-color:

console.log($(row_id).css('background-color'));

And do you know what? Simply getting the background-color color made everything work:

function tbody_get_style(row_id) {
    $('tbody').load("load_tbody.php", function() {
        $(row_id).css('background-color');
        $(row_id).addClass('green');
    });
}

Just adding the line $(row_id).css('background-color'); which seemingly does nothing at all causes the transition effect to work. Here's a demo:

http://so-37035335-b.dev.zuma-design.com/

I'm just dumbfounded by this. Why does this work? Is it merely adding a small delay or does jQuery getting the css property somehow have a substantial effect on the state of the newly added element?

解决方案

When element is added, reflow is needed. The same applies to adding the class. However when you do both in single javascript round, browser takes its chance to optimize out the first one. In that case, there is only single (initial and final at the same time) style value, so no transition is going to happen.

The setTimeout trick works, because it delays the class addition to another javascript round, so there are two values present to the rendering engine, that needs to be calculated, as there is point in time, when the first one is presented to the user.

There is another exception of the batching rule. Browser need to calculate the immediate value, if you are trying to access it. One of these values is offsetWidth. When you are accessing it, the reflow is triggered. Another one is done separately during the actual display. Again, we have two different style values, so we can interpolate them in time.

This is really one of very few occasion, when this behaviour is desirable. Most of the time accessing the reflow-causing properties in between DOM modifications can cause serious slowdown.

The preferred solution may vary from person to person, but for me, the access of offsetWidth (or getComputedStyle()) is the best. There are cases, when setTimeout is fired without styles recalculation in between. This is rare case, mostly on loaded sites, but it happens. Then you won't get your animation. By accessing any calculated style, you are forcing the browser to actually calculate it

Trigger CSS transition on appended element

Explanation For the last part

The .css() method is a convenient way to get a style property from the first matched element, especially in light of the different ways browsers access most of those properties (the getComputedStyle() method in standards-based browsers versus the currentStyle and runtimeStyle properties in Internet Explorer) and the different terms browsers use for certain properties.

In a way .css() is jquery equivalent of javascript function getComputedStyle() which explains why adding the css property before adding class made everything work

Jquery .css() documentation

// Does not animate
var $a = $('<div>')
    .addClass('box a')
    .appendTo('#wrapper');
    $a.css('opacity');
    $a.addClass('in');


// Check it's not just jQuery
// does not animate
var e = document.createElement('div');
e.className = 'box e';
document.getElementById('wrapper').appendChild(e);
window.getComputedStyle(e).opacity;
e.className += ' in';

.box { 
  opacity: 0;
  -webkit-transition: all 2s;
     -moz-transition: all 2s;
          transition: all 2s;
    
  background-color: red;
  height: 100px;
  width: 100px;
  margin: 10px;
}

.box.in {
    opacity: 1;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div id="wrapper"></div>

Here is the listed work arounds [SO Question]

css transitions on new elements [SO Question]

这篇关于CSS转换在jQuery .load回调失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆