当页面加载时,使用Javascript将src属性写为data-src

时间:2015-04-11 13:04:33

标签: javascript html5 user-agent

  

背景:早在十二月,我想要我的(自定义)PHP页面构建   如果用户代理(UA)可以处理,则引擎单向构建页面   如果UA不能,Javascript和不同的方式。要做到这一点,我   需要学习:

     

如何在PHP构建页面之前通过PHP检测UA Javascript功能:   Detecting javascript in PHP, before PHP builds page

     

感谢@skobaljic,@ Abhi Beckert提供的一些非常有用的指导   和@GolezTrol,我了解到我们可以使用Javascript来放置   一个会话cookie,PHP将能够在所有后续页面上查询   负载。因此,对于第一个之后的每个页面,PHP都会   知道 UA是否具有Javascript功能

     

到目前为止,这么好。现在我已经到了不再是我的舞台   使用PHP即时构建页面,但预先生成并上传   它们作为静态HTML文档到服务器。

     

如果你还在我身边,你会猜对了,这意味着我   目前需要为每个页面预生成两个静态文档 -   一个用于支持JS的UA,一个用于支持JS的UA。   这不是很理想,因此我的问题如下。

从表面上看,这看起来应该是一个直截了当的问题。

对于Javascript无能力的UAs,我想构建一个包含这样的行的文档:

<img src="/myfolder/myimage.png" alt="My Image" />

对于支持Javascript的UAs,我想构建包含这样的行的同一文档:

<img data-src="/myfolder/myimage.png" alt="My Image" />

(对于那些好奇的人来说,onload之后的javascript会将所有data-src属性转换为src属性,然后继续进行数十次服务器往返,但至关重要的是 - 页面已经大量加载之后。

我已经通过PHP和会话cookie实现了这一点(参见上面的背景),但现在,如果可能的话,我想在前端执行整个事情。

默认情况下,如何将属性写入DOM中的<img />元素src,另外,(如果javascript可用)将该属性作为data-前缀,以便它读为data-src ...

......这样......

[重要位]

如果 ,UA具有javascript功能,它会自动立即将src的所有实例写为data-src 作为页面正在由UA 下载,以便在onload之后,javascript可以再次将data-src的所有实例重新编写为src

3 个答案:

答案 0 :(得分:1)

像这样 - 未经测试但应该有效:

var imgs = document.getElementsByTagName('img');

for(var i = 0; i < imgs.length; i++) {
  var currentSrc = imgs[i].getAttribute('src');
  imgs[i].setAttribute('src',''); // remove old src data 
  imgs[i].setAttribute('data-src','currentSrc');
}

所有这一切都是添加新的data-src属性,并清除当前的src(如果需要)

</body>代码

之前添加

答案 1 :(得分:1)

这是一种hacky方式,但所有浏览器(ie6 +)都支持它:

<body>

    <noscript>
         <style>.img-hide { display: none; }</style>
    </noscript>

    <noscript><img src="/path/to/image1.jpg"></noscript>
    <img class="img-hide" data-src="/path/to/image1.jpg">

    <noscript><img src="/path/to/image2.jpg"></noscript>
    <img class="img-hide" data-src="/path/to/image2.jpg">

    <!-- etc etc etc -->

</body>

答案 2 :(得分:1)

经过将近3天的搔痒,我终于破解了这一点。

<强> 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>

更新1

感谢Dave Walsh的文章引用脚本自己的标记http://davidwalsh.name/script-tag),我重写了{{1}的前3行}:

function initialiseImages()

作为一行:

    var scripts = document.getElementsByTagName('script');
    var section = scripts[scripts.length-1].parentNode;
    var images = section.getElementsByTagName('img');

据我所知,这会更快地定义var images = document.currentScript.parentNode.getElementsByTagName('img'); ,因此在UA向服务器发送文件请求之前会捕获更多var images的实例。


开发人员备注遵循...

尝试#1:尝试使Javascript行为像PHP

我更熟悉在PHP中动态编写页面而不是部署Javascript,因此我的初衷是找到一种以准服务器端方式使用Javascript重写的方法DOM在它到达的那一刻即刻发生:

  

对于Javascript无能力的UA,我想构建一个文档   包含这样的行:

<img src=
     

对于支持Javascript的UAs,我想构建相同的文档   包含这样的行:

<img src="/myfolder/myimage.png" alt="My Image" />

如果这种方法成为可能,我无法找到方法 - 而且,公平地说,Javascript当然不是为了在元素属性到达时即刻重写元素属性而设计的。 / p>

尝试#2:通过添加Javascript的CSS

阻止图像下载

我的第二种方法是看看我是否可以通过一系列CSS阻止图像下载。

如果我使用Javascript添加该行,则只有支持Javascript的UA才能读取图像阻塞样式规则。

这也没有用。事实证明,通过将<img data-src="/myfolder/myimage.png" alt="My Image" /> 应用于具有background-images的元素的父容器,您可以直接阻止CSS display:none;下载。但是我要阻止的图像(直到onload之后)具体为background-image,而不是<img>s - 事实证明,只要UA命中background-images,它就会运行到服务器下载图像。

尝试#3:每个<img src

中的内联Javascript

内联Javascript非常古老,但@Darren Sweeney已经提出了一个富有想象力的<img>解决方案,所以我不想自动解雇老派。我想过要解决这个问题:

<noscript>

我遇到的主要问题是我找不到合适的<img src="/myfolder/myimage.png" alt="My Image" onEvent="initialiseImage();" /> 。我将onEvent函数放在initialiseImage()中,然后我希望每次UA到达<head>时都会自动触发该函数 - 但经过大量阅读后,我不确定可以自动执行内联。 (也许有人可以在下面的评论中告诉我,如果是......)

当然,我找不到<img>

唯一有意义的元素onParseonEvent,在onLoad的情况下(如果我理解正确的话)下载<img>之前它开火了。所以这根本不好。

尝试#4:最后成功!

到目前为止:

1)从一开始,问题是在使用Javascript重写每个<img>属性之前等到window.onload为时已太晚;

2)我无法在下载时立即使用Javascript重写每个<img src=;

3)我无法在UA解析<img src=的时候看到使用Javascript重写每个<img src=属性的方法;

我推断,在UA完成解析包含每组<img>的每个<img src=时,我仍然可以使用Javascript重写每个<section>属性。

我很高兴地说我已经相当彻底地测试了上面的代码,并且看起来(到目前为止)工作完美 - 早在UA开始从服务器请求<img>s文件之前,{{1} }属性已替换为<img>属性,并且该请求不再执行。