bil*_*oah 12 html javascript css jquery css3
我有一个函数,使用jQuery将html加载到一个表中,然后使用回调向其中一行添加一个类.该功能由页面上的各种UI驱动事件触发.我也有一个css转换规则,所以颜色应淡入(transition: background-color 1000ms linear).该函数如下所示:
function load_tbody(row_id) {
$('tbody').load("load_tbody.php", function() {
$(row_id).addClass('green');
});
}
Run Code Online (Sandbox Code Playgroud)
加载html后,成功添加类并将行颜色设置为绿色.但是,我的css转换规则似乎被忽略了.
当我添加一点延迟,甚至10毫秒时,它工作正常:
function load_tbody(row_id) {
$('tbody').load("load_tbody.php", function() {
setTimeout(function() {
$(row_id).addClass('green');
}, 10);
});
}
Run Code Online (Sandbox Code Playgroud)
状态的jQuery文档.load():
如果提供"完整"回调,则在后处理和执行HTML插入之后执行.
对我而言,这将表明新元素已加载到dom中,并且已应用现有样式并且可以进行操作.为什么转换在第一个示例中失败但在第二个示例中成功?
这是一个功能齐全的示例页面,用于演示相关行为:
http://so-37035335.dev.zuma-design.com/
虽然上面的例子从cdn链接了jQuery 2.2.3版,但实际的页面使用的是版本1.7.1.两个版本都可以观察到相同的行为.
更新:
在考虑了下面提供的一些评论和答案之后,我偶然发现了一些令人困惑的事情.用户@gdyrrahitis提出了一个建议,引导我这样做:
function tbody_fade(row_id) {
$('tbody').load("load_tbody.php", function() {
$('tbody').fadeIn(0, function() {
$(this).find(row_id).addClass('green');
});
});
}
Run Code Online (Sandbox Code Playgroud)
在fadeIn()回调中添加类可以工作,即使持续时间为0ms.因此,这让我想知道......如果元素是理论上反正有什么背景颜色做浏览器认为它之前,我补充一点类.所以我记录了background-color:
console.log($(row_id).css('background-color'));
Run Code Online (Sandbox Code Playgroud)
你知道吗?只需获得背景色的颜色就可以了:
function tbody_get_style(row_id) {
$('tbody').load("load_tbody.php", function() {
$(row_id).css('background-color');
$(row_id).addClass('green');
});
}
Run Code Online (Sandbox Code Playgroud)
只是添加$(row_id).css('background-color');似乎什么都不做的行会导致过渡效果起作用.这是一个演示:
http://so-37035335-b.dev.zuma-design.com/
我只是傻眼了.为什么这样做?它只是添加一个小延迟或jQuery获取css属性以某种方式对新添加的元素的状态产生实质性影响?
jQuery load旨在删除页面中请求的所有内容.
您可以Deferred使用jQuery 对象的强大功能$.get.
看看这个插头.
来自plunk的代码片段
function load_tbody(row_id) {
$.when($.get("load_tbody.html", function(response) {
$('tbody').hide().html(response).fadeIn(100, function() {
$(this).find(row_id).addClass('green');
});
}));
}
Run Code Online (Sandbox Code Playgroud)
我正在使用$.when它将在$.get解决后立即运行其回调,这意味着将获取HTML响应.在获取响应之后,将其附加到tbodyfadedIn(fadeIn方法),并在显示之后,将.green类添加到所需的行.
请注意,如果您继续将html附加到该类,然后将该类附加到该类row_id,您将无法看到转换,因为它会立即执行.一个小小的视觉技巧与fadeIn可以做的工作.
更新
在新添加到DOM的元素上,transition不会触发CSS3 .这主要是因为内部浏览器引擎控制所有动画.有很多关于该问题的解决方法的文章,以及stackoverflow答案.可以在那里找到其他资源,我相信这可以比我更好地解释这个主题.
这个答案是关于退后一步并改变在DOM中呈现动态元素的功能,而不会使用setTimeout或requestAnimationFrame.这是通过jQuery在浏览器中运行时以清晰一致的方式实现您想要实现的目标的另一种方式.这fadeIn(100, ...是了解浏览器即将渲染的下一个可用框架所需要的.它可能会少得多,价值只是为了满足视觉美学.
另一种解决方法是根本不使用转换,animation而是使用转换.但是从我的测试中,这在IE Edge中失败,在Chrome,Firefox上运行良好.
请查看以下资源:
更新2
请看一下规范,因为有关CSS3的有趣内容transitions.
...对一组同时样式更改的处理称为样式更改事件.(实现通常具有样式更改事件以与其所需的屏幕刷新率相对应,并且当依赖于它的脚本API需要最新的计算样式或布局信息时.)
由于此规范未定义样式更改事件何时发生,因此对计算值的哪些更改被同时考虑,因此作者应注意在进行可能转换的更改后,在少量时间内更改任何转换属性可导致实现之间的行为不同,因为在某些实现中可能会同时考虑更改,而在其他实现中则不会.
当样式更改事件发生时,实现必须根据在该事件中更改的计算值开始转换.如果在该样式更改期间元素不在文档中,或者在上一个样式更改事件期间不在文档中,则不会在该样式更改事件中为该元素启动过渡.
当添加元件时,需要回流焊。这同样适用于添加类。然而,当您在单个 JavaScript 轮中执行这两项操作时,浏览器会利用机会优化第一个轮次。在这种情况下,只有单个(同时是初始和最终)样式值,因此不会发生任何转换。
setTimeout 技巧起作用了,因为它延迟了将类添加到另一轮 javascript 的时间,因此渲染引擎需要计算两个值,因为当第一个值呈现给用户时存在时间点。
批处理规则还有另一个例外。如果您尝试访问它,浏览器需要计算立即值。这些值之一是 offsetWidth。当您访问它时,就会触发回流。另一项是在实际展示时单独完成的。同样,我们有两个不同的样式值,因此我们可以及时对它们进行插值。
这确实是极少数需要这种行为的情况之一。大多数时候,在 DOM 修改之间访问导致回流的属性可能会导致严重的速度减慢。
首选的解决方案可能因人而异,但对我来说,offsetWidth(或getComputedStyle())的访问是最好的。在某些情况下,setTimeout 被触发时,中间没有重新计算样式。这种情况很少见,主要是在加载的网站上,但它确实发生了。那么你将无法获得动画。通过访问任何计算的样式,您将强制浏览器实际计算它
.css() 方法是从第一个匹配元素获取样式属性的便捷方法,特别是考虑到浏览器访问大多数这些属性的方式不同(基于标准的浏览器中的 getCompulatedStyle() 方法与 currentStyle 和 runtimeStyle Internet Explorer 中的属性)以及浏览器对某些属性使用的不同术语。
在某种程度上 .css() 是 jquery 等价于 javascript 函数getComputedStyle(),这解释了为什么在添加类之前添加 css 属性使一切正常
// 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';Run Code Online (Sandbox Code Playgroud)
.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;
}Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div id="wrapper"></div>Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
916 次 |
| 最近记录: |