That's interesting. I was asking myself the exact same question recently. Another method would be to create a DOM element for each element and wait until you need to display it before injecting it into the document body. For example,
var img1 = document.createElement('img');
var img2 = document.createElement('img');
img1.setAttribute('src','imageName1.gif');
img2.setAttribute('src','imageName2.gif');
...and then later, when you know the images are ready to be inserted...
document.getElementById('imagePlaceholder1').appendChild(img1);
document.getElementById('imagePlaceholder2').appendChild(img2);
This does result in the file getting 'pre-loaded' in the modern browsers I tested and it may actually be more consistent with your own coding styles, but I'm still worried that some browsers might not load the image at the time of the element creation but wait until it's added to the document body. So I opted to use the exact solution you mentioned. At least until the next update to ECMAScript, there's nothing wrong with "old code" (at least old code like new Image()). It works and it was intended to work this way. I don't think it's particularly hacky.
[Edit] The second block of code should be made to execute when you are sure the images have loaded and/or when the user does whatever it is you expect him or her to do that triggers its appearance.