onAvailable() doPoll trigger once

Hi,
I’m following peter.michaux.ca - The window.onload Problem (Still) with this code


<html>
 <head>

<script type="application/javascript">
var stack = [],
    interval,
    loaded; // has window.onload fired?

function doPoll() {
  var notFound = [];
alert(stack.length);
  for (var i=0; i<stack.length; i++) {
    if (document.getElementById(stack[i].id)) {
      stack[i].callback();
    } else {
      notFound.push(stack[i]);
    }
  }
  stack = notFound;
  if (notFound.length < 1 || loaded) {
    stopPolling();
  }
}

function startPolling() {
  if (interval) {return;}
  interval = setInterval(doPoll, 10);
}

function stopPolling() {
  if (!interval) {return;}
  clearInterval(interval);
  interval = null;
}

function onAvailable(id, callback) {
  stack.push({id:id, callback:callback});  
  startPolling();
}

window.onload = function() {
  loaded = true;
  doPoll();
};
onAvailable('google', function(){
  document.getElementById('google').onclick = function() {alert(this.id);};
});
onAvailable('yahoo', function(){
  document.getElementById('yahoo').onclick = function() {alert(this.id);};
});


</script>
</head>
<body>
  <h1>Search Engines</h1>
  <div><ul id="engines">
    <li id="google">Google</li>
    <li id="yahoo">Yahoo!</li>
  </ul></div>

</body>
</html>



I’m waiting to see alert(stack.length)
trigger three times
once on window.onload
twice setInterval(doPoll, 10);
but I see it once why ?
Can you explain me, please ?

Thanks

Your trying to ask your script to search for 2 elements which don’t exist on the page yet, when using document.[B]getElementById/B it either needs to be loaded within window.[B]onload/B or before the ending </body> element on the page. See the examples below

Loaded within window.[B]onload/B

window.onload = function() {
    loaded = true;
    doPoll();
    
    onAvailable('google', function(){
        document.getElementById('google').onclick = function() {alert(this.id);};
    });
    
    onAvailable('yahoo', function(){
        document.getElementById('yahoo').onclick = function() {alert(this.id);};
    });
};

Loaded before the ending </body> element

<script type="text/javascript">
onAvailable('google', function(){
    document.getElementById('google').onclick = function() {alert(this.id);};
});

onAvailable('yahoo', function(){
    document.getElementById('yahoo').onclick = function() {alert(this.id);};
});
</script>

</body>

actually the snippet works

in the tutorial (It’s just about to avoid window.onload and bottom script tag technique)

The Yahoo! UI event library has two functions to help implement unobtrusive JavaScript and these functions cleverly avoid all the assumptions and problems of the bottom script and Dean Edwards script. Instead of trying to determine when the entire DOM is ready, the YUI library polls the DOM with document.getElementById() until a particular element is found or the window.onload event fires. When document.getElementById() does finally return the element then the element is clearly in the DOM and it should be relatively safe to add event listeners to the element.