javascript竞争条件
我正在调用一个javascript函数,该函数可以快速连续地将iframe的不透明度设置为未知的次数。基本上这将alpha从0变为100。 这是密码javascript竞争条件,javascript,Javascript,我正在调用一个javascript函数,该函数可以快速连续地将iframe的不透明度设置为未知的次数。基本上这将alpha从0变为100。 这是密码 function setAlpha(value) { iframe.style.opacity = value * .01; iframe.style.filter = 'alpha(opacity =' + val + ')'; } 我的问题是它第一次在IE7中工作,而不是在firefox 3.
function setAlpha(value)
{
iframe.style.opacity = value * .01;
iframe.style.filter = 'alpha(opacity =' + val + ')';
}
我的问题是它第一次在IE7中工作,而不是在firefox 3.02中。在Firefox中,我得到一个延迟,然后contentdocument以100的不透明度出现。如果我在其中插入一个警报,那么我猜这是一个竞争条件,尽管我认为javascript是单线程的,并且在最后一个函数完成执行之前调用了setAlpha函数。
任何帮助都将不胜感激。我读过“避免javascript竞态条件”这篇文章,但我认为这是不同的,而且我不知道如何将该示例应用到这篇文章中。javascript不会跨多个线程运行,因此您可以避免竞态条件,忽略Safari和Firefox:D中即将出现的工作线程支持 简单的问题,你是如何多次调用setAlpha的,firefox,safari和opera都会合并样式表更新-例如,当js运行时,他们不会重新绘制甚至重新绘制样式信息,除非他们必须这样做。因此,只有在JS完成后,他们才会进行绘制 所以如果你在做
while(...) setAlpha(...)
它们不会更新,您可能需要使用setTimeout触发多个不同的调用来更新样式
另一种方法是使用jQuery、mootools等库,我隐约记得这些库提供了一种简化的机制来执行这些类型的动画和转换。作为一个额外的好处,我相信至少有一些库在可用时也会使用webkit转换和动画css规则,例如Safari,我认为最新的firefox版本
[编辑:警告:我实际上没有使用这些库中的任何一个,我只了解它们应该做什么。我的网站在lynx中呈现出与其他浏览器相同的效果,因为我无法设计出摆脱纸袋的方式:D]Javascript不会跨多个线程运行,因此您不会受到竞争条件的影响,从而忽略Safari和Firefox:D中即将推出的工作线程支持 简单的问题,你是如何多次调用setAlpha的,firefox,safari和opera都会合并样式表更新-例如,当js运行时,他们不会重新绘制甚至重新绘制样式信息,除非他们必须这样做。因此,只有在JS完成后,他们才会进行绘制 所以如果你在做
while(...) setAlpha(...)
它们不会更新,您可能需要使用setTimeout触发多个不同的调用来更新样式
另一种方法是使用jQuery、mootools等库,我隐约记得这些库提供了一种简化的机制来执行这些类型的动画和转换。作为一个额外的好处,我相信至少有一些库在可用时也会使用webkit转换和动画css规则,例如Safari,我认为最新的firefox版本
[编辑:警告:我实际上没有使用这些库中的任何一个,我只了解它们应该做什么。我的网站在lynx中呈现出与任何其他浏览器相同的效果,因为我无法设计出摆脱纸袋的方式:D]一些浏览器足够聪明,可以延迟对DOM的更改,直到调用堆栈为空为止 这通常是一件明智的事情。例如,如果调用将元素更改为黄色的函数,并立即调用将同一元素更改回其原始状态的函数,则浏览器不应浪费时间进行更改,因为更改发生得太快,以至于用户无法察觉 setTimeOutpunc,0技巧通常用于强制Javascript延迟func的执行,直到调用堆栈为空 代码:
function setAlpha(opacity){
some_element.style.opacity = opacity;
}
/**
* This WON'T work, because the browsers won't bother reflecting the
* changes to the element's opacity until the call stack is empty,
* which can't happen until fadeOut() returns (at the earliest)
**/
function fadeOut(){
for (var i=0; i<10; i++){
setAlpha(0.1*i);
}
}
/**
* This works, because the call stack will be empty between calls
* to setAlpha()
**/
function fadeOut2(){
var opacity = 1;
setTimeout(function setAlphaStep(){
setAlpha(opacity);
if (opacity > 0){
setTimeout(setAlphaStep, 10);
}
opacity -= 0.1;
}, 0);
}
所有这些都归结为一个很好的借口,可以使用许多javascript库中的一个来处理这些棘手的东西
编辑:这里有一个一些浏览器足够聪明,可以延迟对DOM的更改,直到调用堆栈为空 这通常是一件明智的事情。例如,如果调用将元素更改为黄色的函数,并立即调用将同一元素更改回其原始状态的函数,则浏览器不应浪费时间进行更改,因为更改发生得太快,以至于用户无法察觉 setTimeOutpunc,0技巧通常用于强制Javascript延迟func的执行,直到调用堆栈为空 代码:
function setAlpha(opacity){
some_element.style.opacity = opacity;
}
/**
* This WON'T work, because the browsers won't bother reflecting the
* changes to the element's opacity until the call stack is empty,
* which can't happen until fadeOut() returns (at the earliest)
**/
function fadeOut(){
for (var i=0; i<10; i++){
setAlpha(0.1*i);
}
}
/**
* This works, because the call stack will be empty between calls
* to setAlpha()
**/
function fadeOut2(){
var opacity = 1;
setTimeout(function setAlphaStep(){
setAlpha(opacity);
if (opacity > 0){
setTimeout(setAlphaStep, 10);
}
opacity -= 0.1;
}, 0);
}
所有这些都归结为一个很好的借口,可以使用许多javascript库中的一个来处理这些棘手的东西
编辑:下面是一个您使用的是设置超时还是紧循环?如果只使用循环调用函数,则切换到使用setTimout 例如:
function setAlpha(value)
{
iframe.style.opacity = value * .01;
iframe.style.filter = 'alpha(opacity =' + val + ')';
if(value < 100 ) {
setTimeout(function () {setAlpha(value+1)},20);
}
}
setAlpha(0);
因为你看,单线程的不仅仅是javascript。这是整个该死的浏览器。如果你的javascript陷入了一个死循环,你就会挂起整个浏览器。因此浏览器暂停等待javascript完成,甚至没有机会
在代码快速更改某些dom值时更新屏幕。您使用的是setTimeout还是紧密循环?如果只使用循环调用函数,则切换到使用setTimout 例如:
function setAlpha(value)
{
iframe.style.opacity = value * .01;
iframe.style.filter = 'alpha(opacity =' + val + ')';
if(value < 100 ) {
setTimeout(function () {setAlpha(value+1)},20);
}
}
setAlpha(0);
因为你看,单线程的不仅仅是javascript。这是整个该死的浏览器。如果你的javascript陷入了一个死循环,你就会挂起整个浏览器。因此,浏览器暂停等待javascript完成,甚至没有机会更新屏幕,而您的代码正在快速更改某些dom值。问题是,大多数浏览器在javascript执行暂停之前不会重新绘制 正如其他人所建议的,这可以通过使用setTimeout来解决。但是,我建议使用jQuery或任何javascript库来制作动画。运行setTimeout 100次是个坏主意,因为动画的长度会根据浏览器和用户计算机的速度而变化。制作动画的正确方法是指定动画应该持续多长时间,并检查系统时间以确定动画应该进行多长时间
function fadeIn(elem,animation_length) {
var start = (new Date()).getTime();
var step = function() {
window.setTimeout(function() {
var pct = ((new Date()).getTime() - start)/animation_length;
elem.style.opacity = Math.min(pct,1);
if (pct < 1)
step();
},20);
};
step();
}
[编辑:]以上代码仅用于说明如何根据系统时钟而不是简单的时间间隔制作动画。请使用库制作动画。上面的代码在IE上不起作用,因为IE使用filter:opacityxx而不是opacity。库将为您解决这一问题,并提供一些很好的功能,如完成事件和取消动画的功能。问题是大多数浏览器在javascript执行暂停之前不会重新绘制 正如其他人所建议的,这可以通过使用setTimeout来解决。但是,我建议使用jQuery或任何javascript库来制作动画。运行setTimeout 100次是个坏主意,因为动画的长度会根据浏览器和用户计算机的速度而变化。制作动画的正确方法是指定动画应该持续多长时间,并检查系统时间以确定动画应该进行多长时间
function fadeIn(elem,animation_length) {
var start = (new Date()).getTime();
var step = function() {
window.setTimeout(function() {
var pct = ((new Date()).getTime() - start)/animation_length;
elem.style.opacity = Math.min(pct,1);
if (pct < 1)
step();
},20);
};
step();
}
[编辑:]以上代码仅用于说明如何根据系统时钟而不是简单的时间间隔制作动画。请使用库制作动画。上面的代码在IE上不起作用,因为IE使用filter:opacityxx而不是opacity。库将为您解决这一问题,并提供一些很好的功能,如完成事件和取消动画的功能。能否提供有关如何循环调用此函数的详细信息?能否提供有关如何循环调用此函数的详细信息?