Mad*_*ter 3 javascript css callback css-transitions
我有一个大型游戏项目,在其代码中使用了大量的 jquery。前段时间我去掉了所有的 jquery 并用纯 JS 替换它,但我遇到的一件事是替换游戏中对射弹的 .animation 调用。
看来我应该用 CSS 过渡替换它们,而游戏需要知道过渡何时完成,所以我需要为过渡添加回调。一切都很好,除了当我为弹丸分配新的位置值时,过渡被完全跳过并且没有调用回调。出于某些不道德的原因,如果我将其 css 位置的更改包含在 SetTimeout 中 1 毫秒,它就会开始工作——即使那样,有时它仍然会跳过过渡。
现在它通常可以工作,除了大约 10 次转换将播放但随后不会调用回调。我不知道为什么 settimeout 有助于在那里,我不知道为什么回调有时不起作用。谁能帮我理解?
let tablehtml = '<div id="'+animid+'" style="position: absolute; left: ' + ammocoords.fromx + 'px; top: ' + ammocoords.fromy + 'px; background-image:url(\'graphics/' + ammographic.graphic + '\');background-repeat:no-repeat; background-position: ' + ammographic.xoffset + 'px ' + ammographic.yoffset + 'px; transition: left '+duration+'ms linear 0s, top '+duration+'ms linear 0s;"><img src="graphics/spacer.gif" width="32" height="32" /></div>';
document.getElementById('combateffects').innerHTML += tablehtml;
let animdiv = document.getElementById(animid);
animdiv.addEventListener("transitionend", function(event) {
FinishFirstAnimation();
}, false);
setTimeout(function() { Object.assign(animdiv.style, {left: ammocoords.tox+"px", top: ammocoords.toy+"px" }); }, 1); // THIS IS A TOTAL KLUDGE
// For some reason, the transition would not run if the 1ms pause was not there. It would skip to the end, and not
// fire the transitionend event. This should not be necessary.
Run Code Online (Sandbox Code Playgroud)
基本上,在您设置 new 时style,浏览器仍未应用内联设置,您元素的计算样式仍将其display值设置为""
,因为它是不在 DOM 中的元素的默认值。它left和top计算出的值仍然是0px,即使您确实在标记中设置了它。
这意味着当transition属性将在下一帧绘制之前应用时,left并且top已经是您设置的属性,因此过渡将无关紧要:它不会触发。
为了规避它,您可以强制浏览器执行此重新计算。事实上,一些 DOM 方法需要样式是最新的,因此浏览器将被迫触发也称为回流的东西。
Element.offsetHeightgetter 是这些方法之一:
let tablehtml = `
<div id="spanky"
style="position: absolute;
left: 10px;
top: 10px;
background-color:blue;
width:20px;
height:20px;
transition: left 1000ms linear 0s, top 1000ms linear 0s;">
</div>`;
document.body.innerHTML += tablehtml;
let animdiv = document.getElementById('spanky');
animdiv.addEventListener("transitionend", function(event) {
animdiv.style.backgroundColor='red';
}, false);
// force a reflow
animdiv.offsetTop;
// now animdiv will have all the inline styles set
// it will even have a proper display
animdiv.style.backgroundColor='green';
Object.assign(animdiv.style, {
left: "100px",
top: "100px"
});Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
386 次 |
| 最近记录: |