背景:早在十二月,我想要我的(自定义)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
。
答案 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
的实例。
开发人员备注遵循...
我更熟悉在PHP中动态编写页面而不是部署Javascript,因此我的初衷是找到一种以准服务器端方式使用Javascript重写的方法DOM在它到达的那一刻即刻发生:
对于Javascript无能力的UA,我想构建一个文档 包含这样的行:
<img src=
对于支持Javascript的UAs,我想构建相同的文档 包含这样的行:
<img src="/myfolder/myimage.png" alt="My Image" />
如果这种方法成为可能,我无法找到方法 - 而且,公平地说,Javascript当然不是为了在元素属性到达时即刻重写元素属性而设计的。 / p>
我的第二种方法是看看我是否可以通过一系列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
,它就会运行到服务器下载图像。
<img src
内联Javascript非常古老,但@Darren Sweeney已经提出了一个富有想象力的<img>
解决方案,所以我不想自动解雇老派。我想过要解决这个问题:
<noscript>
我遇到的主要问题是我找不到合适的<img src="/myfolder/myimage.png" alt="My Image" onEvent="initialiseImage();" />
。我将onEvent
函数放在initialiseImage()
中,然后我希望每次UA到达<head>
时都会自动触发该函数 - 但经过大量阅读后,我不确定可以自动执行内联。 (也许有人可以在下面的评论中告诉我,如果是......)
当然,我找不到<img>
。
唯一有意义的元素onParse
是onEvent
,在onLoad
的情况下(如果我理解正确的话)下载<img>
之前它开火了。所以这根本不好。
到目前为止:
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>
属性,并且该请求不再执行。