经过近 3 天的挠头,我终于破解了这个。
头部
<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>
<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>
更新 1
感谢 Dave Walsh 的文章Referencing a Script's own Tag (http://davidwalsh.name/script-tag),我重写了function initialiseImages()的前3行:
var scripts = document.getElementsByTagName('script');
var section = scripts[scripts.length-1].parentNode;
var images = section.getElementsByTagName('img');
单行:
var images = document.currentScript.parentNode.getElementsByTagName('img');
据我所知,这定义了 var images 的速度稍快一些,因此在 UA 向服务器发送文件请求之前捕获了更多 <img src= 的实例。
开发者注释如下...
尝试 #1:尝试让 Javascript 表现得像 PHP
比起部署 Javascript,我更熟悉用 PHP 动态编写页面,所以我的初衷是想找到一种方法,以准服务器端的方式使用 Javascript 来重写 DOM在它到达的那一刻瞬间:
对于不支持 Javascript 的 UA,我想构建一个文档
包含这样的行:
<img src="/myfolder/myimage.png" alt="My Image" />
对于支持 Javascript 的 UA,我想构建相同的文档
包含这样的行:
<img data-src="/myfolder/myimage.png" alt="My Image" />
如果这样的方法可行,我也找不到办法——而且,公平地说,Javascript 肯定不是为在元素属性到达时立即重写元素而设计的。
尝试 #2:通过添加 Javascript 的 CSS 阻止图片下载
我的第二种方法是看看我是否可以通过一行 CSS 阻止图片下载。
如果我用 Javascript 添加该行,则只有支持 Javascript 的 UA 才能读取图像阻止样式规则。
这也不起作用。事实证明,您可以直接阻止 CSS background-images 下载,方法是将display:none; 应用于具有background-image 的元素的父容器。但是我想要阻止的图像(直到 onload 之后)具体是<img>s,而不是background-images - 结果表明,一旦 UA 命中<img src,它就会运行到服务器下载图像。
尝试 #3:在每个 <img> 中嵌入 Javascript
内联 Javascript 相当老派,但@Darren Sweeney 已经提出了一个富有想象力的<noscript> 解决方案,所以我不想自动放弃老派。我想过这样解决这个问题:
<img src="/myfolder/myimage.png" alt="My Image" onEvent="initialiseImage();" />
我在这里遇到的主要问题是我找不到任何合适的onEvent。我将initialiseImage() 函数放在<head> 中,然后我希望每次UA 达到<img> 时自动触发该函数 - 但经过大量阅读,我不确定是否可以内联自动执行。 (也许有人可以在下面的 cmets 中告诉我,如果是...)
当然,我找不到onParse。
唯一有意义的特定于元素的onEvent 是onLoad,在<img> 的情况下(如果我理解正确的话)会在<img> 触发之前下载它。所以这根本不好。
尝试 #4:终于成功了!
到目前为止:
1) 从一开始,问题就在于等到window.onload 再使用Javascript 重写每个<img src= 属性为时已晚;
2) 我看不到使用 Javascript 在下载时立即重写每个 <img src= 的方法;
3) 在 UA 解析 <img> 时,我看不到使用 Javascript 重写每个 <img src= 属性的方法;
我推断,在 UA 完成对包含每组 <img>s 的每个 <section> 的解析时,也许我仍然可以使用 Javascript 重写每个 <img src= 属性。
我很高兴地说,我已经相当彻底地测试了上面的代码,并且它(到目前为止)似乎可以完美运行 - 早在 UA 开始从服务器请求 <img> 文件之前,<img src= 属性已经替换为 <img data-src= 属性,并且不再执行该请求。