document.getElementById的价值是多少?

时间:2012-01-04 22:57:34

标签: javascript javascript-events

我是一名经验丰富的程序员,但我正在努力学习javascript,并通过了解工作原理来学习。我找到了一个淡化数组中图像的脚本。这是脚本

window.addEventListener?window.addEventListener("load",so_init,false):window.attachEvent("onload",so_init);

var d=document, imgs = new Array(), zInterval = null, current=0, pause=false;

function so_init() {
if(!d.getElementById || !d.createElement)return;

css = d.createElement("link");
css.setAttribute("href","xfade2.css");
css.setAttribute("rel","stylesheet");
css.setAttribute("type","text/css");
d.getElementsByTagName("head")[0].appendChild(css);

imgs = d.getElementById("imageContainer").getElementsByTagName("img");
for(i=1;i<imgs.length;i++) imgs[i].xOpacity = 0;
imgs[0].style.display = "block";
imgs[0].xOpacity = .99;

setTimeout(so_xfade,1000);
}

function so_xfade() {
cOpacity = imgs[current].xOpacity;
nIndex = imgs[current+1]?current+1:0;

nOpacity = imgs[nIndex].xOpacity;

cOpacity-=.05; 
nOpacity+=.05;

imgs[nIndex].style.display = "block";
imgs[current].xOpacity = cOpacity;
imgs[nIndex].xOpacity = nOpacity;

setOpacity(imgs[current]); 
setOpacity(imgs[nIndex]);

if(cOpacity<=0) {
    imgs[current].style.display = "none";
    current = nIndex;
    setTimeout(so_xfade,1000);
} else {
    setTimeout(so_xfade,50);
}

function setOpacity(obj) {
    if(obj.xOpacity>.99) {
        obj.xOpacity = .99;
        return;
    }
    obj.style.opacity = obj.xOpacity;
    obj.style.MozOpacity = obj.xOpacity;
    obj.style.filter = "alpha(opacity=" + (obj.xOpacity*100) + ")";
}

}

我遇到困难的部分是这些行

window.addEventListener?window.addEventListener("load",so_init,false):window.attachEvent("onload",so_init);

if(!d.getElementById || !d.createElement)return;

我能找到的所有内容都显示window.addEventListener和d.getElementById分别是窗口和文档对象的方法。那么在没有任何参数的情况下调用它们时它们的值是什么,在这些情况下,什么条件会使它们成立,哪些条件会使它们变错。

4 个答案:

答案 0 :(得分:4)

代码正在检查这些方法是否存在,以及它们是否使用备用方法(浏览器兼容性问题)或中止无论如何都会失败的函数。

这一行:

window.addEventListener?window.addEventListener("load",so_init,false):window.attachEvent("onload",so_init);

正在检查是否存在window.addEventListener。如果确实如此,那就是它。如果它不存在,则调用window.attachEvent。这是为了处理没有addEventListener但具有类似函数attachEvent的旧版IE。大多数理智的程序员会将这种抽象放在一个实用函数或一个垫片中,你可以将其抽象出来,使其脱离正常编程。在IE9之前的所有版本的IE中仍然需要这种逻辑。

这一行:

if(!d.getElementById || !d.createElement)return;
如果getElementByIdcreateElement中的任何一个作为对象d上的属性/方法不存在,

正在中止该函数(提前返回)。不再需要此检查,因为这些方法存在于所有当前使用的浏览器中(添加到5.5中的IE,存在于Firefox,Chrome和Safari中的1.0)。

答案 1 :(得分:2)

if(!d.getElementById || !d.createElement)return;

此行测试是否存在方法,即它测试浏览器是否支持这两种方法。处理浏览器兼容性并不好玩,但最好是测试功能而不是浏览器版本。

答案 2 :(得分:2)

如果使用没有括号的函数名称,它不会调用该函数,它会为您提供对该函数的引用。一个非常简单的例子:

function f1() { alert("hi"); }

var f2 = f1;    // This doesn't call the f1 function, it takes a reference
                // to it and assigns it to f2.
f2();           // Can call f2 since it refers to the same function; alerts "hi"

你可以看到,函数名称实际上只是变量,它恰好包含对函数的引用而不是字符串或数字或者其他东西,如果你定义这样的函数,这可能更加明显:

var f3 = function() { alert("hello") };
f3();           // "hello"

那么,在那个背景下说if (someFunctionName)是什么意思?在JS中,表达式被认为是“truthy”,不仅如果它是布尔值true,而且它的计算结果是非空字符串,非零数字或任何对象(甚至是空对象)。空字符串,零,空,未定义和NaN都是“假的”。布尔值true和“truthy”之间的区别在JavaScript中非常重要。 JS函数是一种对象。所以:

if (someFunctionName)
// is testing if someFunctionName is "truthy" and is a shortcut way of saying
if (someFunctionName != undefined)
// also equivalent to
if (typeof someFunctionName != "undefined")

您询问的第二个示例if(d.getElementById)是一个测试,对象d(设置为document)有一个名为getElementById的方法。在一般意义上,这是因为很久以前并非所有浏览器都支持该方法,因此该代码旨在允许代码在所有浏览器中运行而不会出现错误。实际上至少从IE5开始就支持document.getElementById(),所以这个测试是多余的。

您询问的第一个示例仍然相关,因为IE8及更早版本不支持window.addEventListener。所以代码:

window.addEventListener ? window.addEventListener("load",so_init,false)
                        : window.attachEvent("onload",so_init);

使用三元运算符? :来测试是否定义了window.addEventListener。如果是,则调用它,否则调用window.attachEvent(这是旧的IE等价物)。所有现代浏览器都支持其中一种。

答案 3 :(得分:1)

在这两种情况下,脚本似乎都在练习渐进enhancement techniques和优雅的降级技术。查看文章,但简而言之,它正在检查浏览器是否支持这些功能。