.getElementById works only once

in Script development
Subscribe to .getElementById works only once 5 posts, 3 voices

JonnyRobbie Scriptwright

My userscript http://userscripts.org/scripts/show/149591 works only in Opera and that only after it is reloaded a few times...(why), but in Chrome or Firefox, it seems like the only first instance of getelementbyid works

var down = document.getElementById('tsf');
down.style.width = '310px';
down.style.marginRight = '60px';

the next line seems like it doesn't work...

var down5 = document.getElementById('gs_id0');
down5.style.height = '47px';

I checked several times and the elements with those ids are present, so it should work. I'm lost.

Vivre Scriptwright

if an element occurs more than once you need to shuffle through all of them (otherwise the command is 'done' when a first true result is found).
Just like you do it in your script with eg
var box1 = document.getElementsByClassName('jhp');
for (i=0;i<box1.length;++i)>

Jefferson Scher Scriptwright

What error do you get in Firefox's Error Console (Ctrl+Shift+j) when that line is executed? Or is an earlier error stopping the script before it gets to that line?

Because many parts of Google search are added dynamically by client-side scripts, there may be some timing issues in finding elements in the page. You could try putting your code in a function and then trying both to execute the function immediately and after a brief delay (e.g., window.setTimeout(myfunction, 500);).

JonnyRobbie Scriptwright

@vivre: I thought that when element has an Id, an element with that id is supposed to be there only once since ID is the unique identifier. That is why I did the loop with the get...byClass.
@Jefferson: it actually might be the issue, since when I installed firebug and tried the slow step by step debugging, all commands did work fine and the script executer rather well. However using setTimeout in this case seems rather kludgy, is there some other function executing code after a page is loaded?

Jefferson Scher Scriptwright

Generally speaking, Greasemonkey scripts run after the content specified in the HTML has loaded but not necessarily after scripts have run. In your script, you can create an event listener or mutation observer to re-run one or more functions after the page has changed. This can have serious performance implications, so it's generally reserved for cases where the timing of changes is unpredictable. For examples of the code, see these scripts:

MutationObserver (modern browsers only)

Event listener on DOMSubtreeModified

Both, in the alternative

Or... using repeated calls to setTimeout (up to a max number)