After nearly 3 days of head-scratching, I've finally cracked this.
HEAD
<head>
<script>
function initialiseImages() {
var scripts = document.getElementsByTagName('script');
var section = scripts[scripts.length-1].parentNode;
var images = section.getElementsByTagName('img');
for (var i = 0; i < images.length; i++) {
var src = images[i].getAttribute('src');
var datasrc = document.createAttribute('data-src');
datasrc.value = src;
images[i].setAttributeNode(datasrc);
images[i].removeAttribute('src');}}
</script>
</head>
BODY
<body>
<section>
<h2><img src="/myfolder/myimage.png" alt="My Image" />Second Level Heading</h2>
<ul><li><img src="/myfolder/myimage.png" alt="My Image" /></li></ul>
<script>initialiseImages();</script>
</section>
<section>
<h3>Third Level Heading</h3>
<ul>
<li><img src="/myfolder/myimage.png" alt="My Image" /></li>
<li><img src="/myfolder/myimage.png" alt="My Image" /></li>
<li><img src="/myfolder/myimage.png" alt="My Image" /></li>
</ul>
<script>initialiseImages();</script>
</section>
</body>
Update 1
Thanks to Dave Walsh's article Referencing a Script's own Tag (http://davidwalsh.name/script-tag), I have re-written the first 3 lines of function initialiseImages():
var scripts = document.getElementsByTagName('script');
var section = scripts[scripts.length-1].parentNode;
var images = section.getElementsByTagName('img');
as a single line:
var images = document.currentScript.parentNode.getElementsByTagName('img');
As far as I can tell, this defines var images fractionally faster and consequently catches more instances of <img src= before the UA sends a file-request to the server.
Developer Notes follow...
Attempt #1 : Try to get Javascript to behave like PHP
I'm much more familiar with writing pages on-the-fly in PHP than with deploying Javascript, so my original intention was to find a way to use Javascript in a quasi-server-side manner to re-write the DOM instantaneously at the very moment it arrived:
For Javascript-non-capable UAs, I want to build a document which
contains lines like this:
<img src="/myfolder/myimage.png" alt="My Image" />
For Javascript capable UAs, I want to build the same document which
contains lines like this:
<img data-src="/myfolder/myimage.png" alt="My Image" />
If such an approach is possible, I couldn't find a way to do it - and, to be fair, Javascript certainly isn't designed for instantaneously re-writing element properties the moment they arrive.
Attempt #2 : Block image download via Javascript-added CSS
My second approach was to see if I could prevent image download via a line of CSS.
If I added that line with Javascript, only Javascript-capable UAs would be able to read the image-blocking style rule.
This didn't work either. It turns out, you can straightforwardly prevent CSS background-images from downloading, by applying display:none; to the parent container of the element which has the background-image. But the images I want to block (until after onload) are specifically <img>s, not background-images - and it turns out that as soon as the UA hits <img src, it runs off to the server to download the image.
Attempt #3 : Inline Javascript in every <img>
Inline Javascript is pretty old-school, but @Darren Sweeney has already suggested an imaginative <noscript> solution, so I didn't want to automatically dismiss old-school. I thought about tackling the issue something like this:
<img src="/myfolder/myimage.png" alt="My Image" onEvent="initialiseImage();" />
The main issue I ran into here was I couldn't find any appropriate onEvent. I placed the initialiseImage() function in the <head> and then I wanted to have that function automatically fire every time the UA reached an <img> - but after extensive reading, I'm not sure that automatic execution inline is possible. (Perhaps someone can let me know in the comments below, if it is...)
Certainly, I could find no onParse.
The only element-specific onEvent that made sense was onLoad, which, in the case of an <img> (if I understand it correctly) downloads the <img> before it fires. So that was no good at all.
Attempt #4 : Success at last!
Thus far:
1) From the start, the issue was that waiting until window.onload before using Javascript to rewrite every <img src= attribute was far too late;
2) I couldn't see a way to use Javascript to rewrite every <img src= instantly as it was downloading;
3) I couldn't see a way to use Javascript to rewrite every <img src= attribute just at the point the UA had parsed the <img>;
I reasoned that perhaps I could still use Javascript to rewrite every <img src= attribute at the moment the UA completed parsing each <section> containing each set of <img>s.
I am delighted to say I have tested the code above fairly thoroughly and it appears (so far) to work perfectly - long before the UA starts to request the <img> files from the server, the <img src= attribute has been replaced with a <img data-src= property and that request is no longer executed.