views:

64

answers:

3

i got a null object when i try to fetch an element by id using prototype's $ function, and got this strange behaviour:

document.observe('dom:loaded', function() {
  $$('.answer').each(function(answer) {
    console.log('answer.id: ' + answer.id);
    console.log('$(answer.id): ' + $(answer.id)); # works, so the element does exists
    console.log("$('answer_73'): " + $('answer_73')); # this doesn't, why?..
    console.log(' ');
  }); 
});

the divs are like this:

<div id="answer_73" class="answer"> ...

and there's no markup error

the logs:

....
answer.id: answer_73
$(answer.id): [object HTMLDivElement]
$('answer_73'): null
....

updated

sorry for all, finally i found what't gone wrong.. it's simply a type:

<div class="answer" id="answer_<%= answer.id %> " 

it's the trailing whitespace which cause this 'strange' behaviour. maybe the prototype lib strips the trailig id when returning an object's id so the error didn't occur in the first case.

+1  A: 

You're in documents's scope there. I'd also suggest you to use Firebug's console.log() function instead of alert() for debugging, then edit your topic.

Kemo
I deleted my comment before you posted your response. It was sarcastic, not an actual stack overflow rule. I just thought it a little rude to ask someone to edit their topic to use your preferred logging method.
Josh Einstein
It was just a friendly recommendation, not making someone use what I want him to.
Kemo
thanks kemo, the console.log is awesome
freenight
+2  A: 

It works for me (Firefox 3.5, latest prototype.js):

<html><head><title></title>
<script src="prototype.js"></script>
<script>
function _debug (msg) {
    document.body.innerHTML += "<p>"+msg+"</p>";
}
document.observe('dom:loaded', function() {
  $$('.answer').each(function(answer) {
    _debug("inside each, .id: "+answer.id);  // works
    _debug("inside each, byId .id: "+document.getElementById(answer.id));
  });
  _debug("outside each, byId literal: "+document.getElementById('answer_73'));
});

</script>
</head><body>

<div id="answer_72" class="answer"></div>
<div id="answer_73" class="answer">foo</div>
<div id="answer_74" class="answer"></div>

</body></html>

results in

foo

inside each, .id: answer_72

inside each, byId .id: [object HTMLDivElement]

inside each, .id: answer_73

inside each, byId .id: [object HTMLDivElement]

inside each, .id: answer_74

inside each, byId .id: [object HTMLDivElement]

outside each, byId literal: [object HTMLDivElement]

Anonymous
+5  A: 

I'll bet you a beer that you have two elements with the id answer_73 in your document.

Pekka
thanks but it's not, since the '$(answer.id)' works
freenight
that doesn't mean you still don't have equal IDs. Since the first `answer.id` will just output the ID depending on the iteration, while the second `$('answer_73')` will look in the entire document for that id, and if found more than one will give you trouble.
Luca Matteis