Javascript 是否可以在不使用事件的情况下检查CSS转换是否完成?
是否可以通过JavaScript验证CSS转换是否已完成,而无需预先注册转换事件 问题是:Javascript 是否可以在不使用事件的情况下检查CSS转换是否完成?,javascript,css-transitions,Javascript,Css Transitions,是否可以通过JavaScript验证CSS转换是否已完成,而无需预先注册转换事件 问题是: 我有一个Web应用程序,它使用CSS转换在页面加载时淡入某些元素 我无法修改此Web应用程序JavaScript代码 当我访问此页面时,我可以在浏览器控制台中执行JavaScript 在继续使用自定义java脚本代码之前,我想确保CSS转换100%完成 在浏览器控制台中,我可以钩住转换事件,但在很多情况下,这会失败,因为: 转换元素还不存在 设置挂钩时,动画已经完成 是否有可能通过JavaScri
- 我有一个Web应用程序,它使用CSS转换在页面加载时淡入某些元素
- 我无法修改此Web应用程序JavaScript代码
- 当我访问此页面时,我可以在浏览器控制台中执行JavaScript
- 在继续使用自定义java脚本代码之前,我想确保CSS转换100%完成
- 在浏览器控制台中,我可以钩住转换事件,但在很多情况下,这会失败,因为:
- 转换元素还不存在
- 设置挂钩时,动画已经完成
您所能做的最好的事情就是查看CSS以查看过渡持续时间。这不是一个答案,而是一个快速构建的POC:
element.onclick=function(){
const color=0x1000 |(Math.random()*0x1000);
const prop=Math.random()<.5?“背景色”:“颜色”;
element.style[prop]=“#”+color.toString(16.slice(-3);
}
设curr={};
requestAnimationFrame(函数检查(){
const prev=当前值;
curr=Object.assign({},getComputedStyle(元素));
const changed=Object.keys(curr.filter)(key=>curr[key]!==prev[key]);
out.innerHTML=changed.map(key=>`${key} `).join(“\n”);
requestAnimationFrame(检查);
});代码>
html,
身体{
宽度:100%;
身高:100%;
保证金:0;
填充:0;
}
#元素{
光标:指针;
宽度:100%;
身高:100%;
填充:20px;
过渡:所有1;
}
点击某处
目前正在过渡:
;
抱歉耽搁了,我正在开会。搜索了我的一个旧项目,但找不到。我将在这里概述这个想法,我最初认为也许我们可以选择突变观察者,但是我们也必须在那里进行定期检查。所以我想这个就行了。首先,你应该避免一些事情:
- 在每一帧调用getComputedStyle是一个坏主意,因为调用和触发layout是一个非常昂贵的func,所以您应该改为节流
- 硬拷贝样式对象,这是一个要复制的大对象,因此您应该传递一个特定属性的参数
- 使用节点引用时,如果节点不在那里,如您所说,这将抛出引用错误,而使用函数返回节点
第一件事是编写一个helper函数,该函数将定期运行一些测试函数,并在成功时返回:
function watchman(obj,test,action,options){
var currentFrame = {value:undefined};
function watch(){
if(test.call(obj,options)){
action.call(obj,options);
return;
} else {
currentFrame.value = window.requestAnimationFrame(watch);
}
};
currentFrame.value = window.requestAnimationFrame(watch);
return currentFrame;
};
接下来是实际的函数,我认为不需要创建新对象,我们可以创建一个包含3(2个可选)参数的函数,节点“functor”,要检查的样式属性,最后是要调用的函数
function onTransitionEnd(fNode,prop,f,precision,timeout){
precision = precision || 5;
timeout = timeout || Infinity;
return new Promise(function(res){
var node = fNode(),
oValue = node && getComputedStyle(node)[prop],
currentFrame = watchman(
fNode,
function(counter){
if(counter.counter * 17 >= timeout){
window.cancelAnimationFrame(currentFrame.value);
}
if(++counter.counter % precision === 0) {
if(!this()){return}
var nValue = getComputedStyle(this())[prop];
if(nValue === oValue) {
return true;
}
oValue = nValue;
}
},
function(counter){
res(f.call(fNode(),prop));
},
{counter:0}
);
});
};
默认精度为5意味着函数将每5个刻度,5*17毫秒检查一次值,以确定转换是否结束。超时也是可选的,它将在一段时间后取消运行
如果节点不在那里,这不是问题,因为我们正在传递一个返回节点或null的函数,如果节点不在那里,它将不会执行
上面是一个承诺,它将返回一个“thenable”对象,您可以根据自己的喜好来链接它
简单用例,例如,在更改样式或类之后:
document.getElementById("someDiv").className = "def c1";
onTransitionEnd(
function(){return document.getElementById("someDiv");},
"transform",
function(){alert("heyy!!");}
);
它现在会提醒你“嘿”。要将此链接:
document.getElementById("someDiv").className = "def c1";
onTransitionEnd(
function(){return document.getElementById("someDiv");},
"transform",
function(prop){alert("heyy!!"); return this;}
).then(function(node){
node.className = "def";
return onTransitionEnd(
function(){return document.getElementById("someDiv");},
"transform",
function(){alert("heyy-2!!"); return this;}
);
}).then(function(node){
alert("id is " + node.id);
});
以下是一些例子:
- )李>
- )李>
- )李>
对于最后一个要工作的,打开开发者控制台,选择蓝色div并将其id更改为“someDiv”,函数将执行
您可能想知道是否在每次更改样式时调用onTransitionEnd,在这种情况下,您可以编写一个包装器。如果你没有主意,告诉我我也会写的
显然,您没有使用包装器,因此这里有一个帮助器包装器:
function Select(node){
this.node = node;
};
Select.prototype.style = function(prop,value,f){
var node = this.node;
this.node.style[prop] = value;
f && onTransitionEnd(
function(){return node;},
prop,
f
);
return this;
};
以下是您将如何使用它:
var selection = new Select(document.getElementById("someDiv"));
selection
.style("width","100px",function(propName){alert(propName + " changed!");})
.style("height","100px",function(propName){alert(propName + " changed!");})
.style("transform","scale(0.5,0.5)",function(propName){alert(propName + " changed!");});
这是一个例子
) 事件意味着有人通知你。不使用事件意味着没有人通知您。这意味着你必须投票。GUI轮询最后一次是在DOS 16位模式下使用的。如果我发现我将发布,我可能正在寻找我的旧项目搜索示例@此外,只要GUI轮询做得好,它就没有问题。“GUI轮询上次是在DOS 16位模式下使用的”。它用于automation@ibrahimtanyalcinGUI轮询不能做得很好,因为这是一个愚蠢的想法。@ceving,“愚蠢”的想法在无法使用更好的想法的情况下是必要的。这不是一个最优解决方案的问题,正如OP所描述的那样,这是不必要的。第二,我建议你在与他人交谈时使用更好的语言,否则至少通过放置真实的个人资料照片来展示“游戏中的皮肤”。thx用于此解决方法!也许我可以用某种方式使用这种hackok-thx。我担心这是真的,但不确定:-/嗨,易卜拉欣!谢谢你的时间!你的解决方案帮助我理解了整个问题。似乎除了反复检查属性是否更改等之外没有其他可能性。例如,如果我稍微修改您的第一个示例,它将失败。“onTransitionEnd”已发出警报,即使动画尚未启动<代码>onTransitionEnd(function(){return document.getElementById(“someDiv”);},“transform”,function(){alert(“heyy!!”);});setTimeout(函数(){document.getElementById(“someDiv”).className=“def c1”;},10000)代码>thx以获取答案。这对我帮助很大!不需要进一步回答:-)那是因为你还缺少1个元素,这就是“包装器”的概念,我问你是否知道