这是一个加载两个图像的简单程序,将第二个图像放在第一个图像的顶部,然后使用setInterval和不透明度更改淡入或淡出顶部图像。它运行得很完美,虽然查看代码,如果在topPic(竞争条件)之前加载botPic,它应该会失败。但它没有,我也无法弄清楚它为什么没有。
window.onload = function() {
var topPic = document.getElementById("topPic");
var botPic = document.getElementById("botPic");
}
function findPosition(obj) {
var curleft = 0;
var curtop = 0;
if (obj.offsetParent) {
do {
curleft += obj.offsetLeft;
curtop += obj.offsetTop;
} while ((obj = obj.offsetParent) !== null);
}
return [curleft, curtop];
}
function doTopPicLoad() {
topPicLoaded = 1;
if (botPicLoaded == 1) {
startFader();
}
}
function doBotPicLoad() {
var leftTop = findPosition(botPic);
topPic.style.left = leftTop[0];
topPic.style.top = leftTop[1];
botPicLoaded = 1;
if (topPicLoaded == 1) {
startFader();
}
}
function startFader() {
// do stuff
}
<img id="botPic" onload='doBotPicLoad()' src="DMH_0991-M-72-720x576.jpg">
<img id="topPic" onload='doTopPicLoad()' src="DMH_0991-72-720x576.jpg">
通过console.log或插入DOM进行记录,始终显示&#34; window.load&#34;作为最后执行的项目。 doTopPicLoad和doBotPicLoad以各种顺序出现,但它们总是将topPic和botPic显示为有效对象。
topPic.onload [object HTMLImageElement] [object HTMLImageElement]
botPic.onload [object HTMLImageElement] [object HTMLImageElement]
startFader
window.onload
但是,如果我这样开始,它通常(总是?)失败。
var topPic;
var botPic;
window.onload = function() {
topPic = document.getElementById("topPic");
botPic = document.getElementById("botPic");
}
我唯一的想法:
Javascript解释器&#34;知道&#34;它必须延迟执行任何引用window.onload函数内声明的任何vars的语句 - 直到该函数完成。 (这似乎很牵强,但它可以解释它。)
我不想在我的代码中留下竞争条件,但似乎没有任何实际的&#34;种族&#34;发生。任何人都可以解释为什么这段代码总是有效吗?
实际例子: http://www.davehennessey.com/photography/small-buildings/DMH_0991X2.html
谢谢 - 戴夫
答案 0 :(得分:0)
您的窗口“加载”处理程序正在设置两个本地变量。您的脚本直接引用“topPic”和“botPic”<img>
DOM元素。如果这两行没有以var
开头,事情就不会真正改变,因为“topPic”和“botPic”已经已经指的是那些将被那些人返回的值致电.getElementById()
。
也就是说,当你的代码(在窗口“load”处理程序之外)引用变量“topPic”和“botPic”时,它所访问的是通过这些名称绑定到窗口对象的DOM元素。浏览器会这样做,因为元素具有那些“id”值。
因为在<img>
元素“加载”事件触发之前不会调用函数,所以事情有效。 (在加载图像之前设置<img>
元素的“样式”将正常工作。)您的窗口“加载”处理程序是多余的,根本不会影响系统。
答案 1 :(得分:0)
Pointy指出,你的topPic和botPic变量只对匿名onload函数是本地的,不会影响页面的其余部分。
您是否考虑过定义Pic类?
function Pic(elem) {
this.elem = elem;
this.loaded = false
}
// define global objects topPic and botPic that have elem and loaded attributes
window.onload = function() {
topPic = new Pic(document.getElementById("topPic"));
botPic = new Pic(document.getElementById("botPic"));
}
function findPosition(obj) {
var curleft = 0;
var curtop = 0;
if (obj.offsetParent) {
do {
curleft += obj.offsetLeft;
curtop += obj.offsetTop;
} while ((obj = obj.offsetParent) !== null);
}
return [curleft, curtop];
}
function doTopPicLoad() {
topPic.loaded = true;
if ( botPic.loaded ) {
startFader();
}
}
function doBotPicLoad() {
var leftTop = findPosition(botPic.elem);
topPic.elem.style.left = leftTop[0];
topPic.elem.style.top = leftTop[1];
botPic.loaded = true;
if ( topPic.loaded ) {
startFader();
}
}
function startFader() {
// do stuff
}