使用JavaScript和CSS转换,我尝试删除CSS类 在动态插入div之后,使用JavaScript和innerHTML。
我真的很惊讶地看到与蓝色div的不透明度相关联的CSS过渡没有按照我想要的方式触发(在Safari下工作,在Chrome下随机工作,在Firefox Dev下无法工作)版)。有人可以解释这种现象吗?
我不确定为什么它的工作方式与红色div的工作方式不同。也许我不知道浏览器如何处理innerHTML?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Having fun with JS</title>
<style>
.std {
width:100px;
height:100px;
opacity: 1;
transition: opacity 5s;
}
.std--hidden {
opacity: 0;
}
.std--red {
background-color: red;
}
.std--blue {
background-color: blue;
}
</style>
</head>
<body>
<button>click here</button>
<div class='std std--red std--hidden'></div>
<div class='insert-here'>
</div>
<script>
// let a chance to the browser to trigger a rendering event before the class is toggled
// see http://stackoverflow.com/a/4575011
setTimeout(function() {
// everything works fine for the red div
document.querySelector('.std--red').classList.toggle('std--hidden');
}, 0);
document.querySelector('button').addEventListener('click', function(e) {
var template = `<div class='std std--blue std--hidden'></div>`;
document.querySelector('.insert-here').innerHTML = template;
setTimeout(function() {
// Why does the CSS transition seems to be triggered randomly ?
// well more exactly
// - it works under my Safari
// - it does not work under my FirefoxDeveloperEdition
// - it works randomly under my Google Chrome
document.querySelector('.std--blue').classList.toggle('std--hidden');
}, 0);
});
</script>
</body>
</html>
所以我只是阅读了CSS transitions specs并找到了这个
一组同时样式更改的处理称为a 风格变化事件。 (实现通常具有样式更改 事件对应于他们所需的屏幕刷新率,以及何时 脚本需要最新的计算样式或布局信息 取决于它的API。)
这可能是某种解释吗?在某些浏览器上,setTimeout 0是否过快,以至于他们没有时间计算样式差异,因此不会触发样式更改事件?事实上,如果使用更长的setTimeout(比如,~16.6666,猜测1/60刷新率......)它似乎无处不在。有人可以证实吗?
答案 0 :(得分:1)
我想我找到了答案,请参阅CSS 3 transition spec:
由于此规范未定义样式更改事件 发生,因此考虑计算值的变化 同时,作者应该意识到改变任何一个 转换属性在进行更改后的少量时间 可能转换可能会导致行为不同 实现,因为可能会同时考虑更改 一些实现,但不是其他实现。
我尝试添加一点延迟让浏览器注意到样式差异并且它一致地工作。似乎有些浏览器执行setTimeout 0的速度比其他浏览器快得多: - )
setTimeout(function() {
document.querySelector('.std--blue').classList.toggle('std--hidden');
}, 17);
答案 1 :(得分:0)
似乎你必须通过引用样式来触发转换。我只是添加了这一行(甚至在console.log中也可以)
document.querySelector('.std.std--blue').style.width = '20';
这里有效:jsfiddle
注意:我正在使用FirefoxDeveloperEdition。
我已遵循此solution:
CSS转换在添加或删除类时不会设置动画,只有在更改CSS属性时才会生成动画。
完整脚本
<script>
setTimeout(function() {
// everything works fine for the red div
document.querySelector('.std--red').classList.toggle('std--hidden');
}, 0);
document.querySelector('button').addEventListener('click', function(e) {
var template = `<div class='std std--blue std--hidden'></div>`;
document.querySelector('.insert-here').innerHTML = template;
document.querySelector('.std.std--blue').style.width = '20';
setTimeout(function() {
document.querySelector('.std.std--blue').style.width = '100';
document.querySelector('.std--blue').classList.toggle('std--hidden');
}, 0);
});
</script>
答案 2 :(得分:-1)
您必须为超时设置一个值,以便为元素插入DOM提供时间(在调用document.querySelector
之前必须存在)
setTimeout(function() { document.querySelector('.std--blue').classList.toggle('std--hidden')},100);
你不需要第一次超时
onload = function() {
document.querySelector('.std--red').classList.toggle('std--hidden');
document.querySelector('button').addEventListener('click', function(e) {
var template = "<div class='std std--blue std--hidden'></div>";
document.querySelector('.insert-here').innerHTML = template;
setTimeout(function() { document.querySelector('.std--blue').classList.toggle('std--hidden')},100);
});
}
&#13;
.std {
width:100px;
height:100px;
opacity: 1;
transition: opacity 5s;
}
.std--hidden {
opacity: 0;
}
.std--red {
background-color: red;
}
.std--blue {
background-color: blue;
}
&#13;
<button>click here</button>
<div class='std std--red std--hidden'></div>
<div class='insert-here'>
</div>
&#13;