简体   繁体   中英

what is the value of document.getElementById?

I am an experienced programmer but I am trying to learn javascript and I learn best by seeing how things work. I found a script that fades images in an array. This is the script

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) + ")";
}

}

The part I am having difficulty with are these lines

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

and

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

Everything I can find shows both window.addEventListener and d.getElementById are methods of the window and document objects respectively. So what is their values when they are called with out any parameters, and in these cases what conditions would make them true and what condition would make them false.

The code is checking to see if those methods exist and if they don't is using alternate methods (browser compatibility issues) or aborting a function that will just fail anyway.

This line:

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

is checking to see if window.addEventListener exists. If it does, it's calling it. If it doesn't exist, it's calling window.attachEvent . This is to deal with older versions of IE that didn't have addEventListener , but had a similar function called attachEvent . Most sane programmers would put this abstraction in a utility function or a shim that you call to abstract this out of normal programming. This logic is still needed in all versions of IE before IE9.

This line:

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

is aborting the function (with an early return) if either of getElementById or createElement don't exist as properties/methods on object d . This check is no longer needed as these methods exist in all currently used browsers (added to IE in 5.5, present in Firefox, Chrome and Safari in 1.0).

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

This line tests to see if the methods exist at all, ie, it tests if the browser supports both methods. Dealing with browser compatibility isn't fun, but it's better to test for functionality rather than browser version.

If you use a function name without parentheses it doesn't call the function, it gives you a reference to the function. A really simple example:

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"

You can see from that the function names are really just variables that happen to hold references to functions rather than to strings or numbers or whatever, something that is perhaps even more obvious if you define a function like this:

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

So, with that background what does it mean to say if (someFunctionName) ? In JS, an expression is considered "truthy" not only if it is a boolean true but if it evaluates to be a non-empty string, a non-zero number, or any object (even an empty object). Empty strings, zero, null, undefined and NaN are all "falsy". This distinction between boolean true and "truthy" is very important in JavaScript. JS functions are a type of object. So:

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")

The second example you ask about, if(d.getElementById) , is a test that the object d (which is set to document ) has a method called getElementById . In a general sense this is because a long time ago not all browsers supported that method so this code was intended to allow the code to run in all browsers without errors. In practice document.getElementById() has been supported since at least the days of IE5 so this test is redundant.

The first example you asked about is still relevant though because IE8 and older does not support window.addEventListener . So the code:

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

is using the ternary operator ? : ? : to test whether window.addEventListener is defined. If it is, it calls it, otherwise it calls window.attachEvent (which is the old IE equivalent). All modern browsers support one or the other.

In both cases, the script seems to be practicing progressive enhancement techniques and graceful degradation techniques. Check out the article, but in short, it's checking whether the browser supports these functions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM