在图片开始加载之前运行javascript是否可能?

12

我想在浏览器请求图片之前更改图片的src属性,目的是使用类似Timthumb的PHP脚本减小图片的大小。使用jQuery,我认为$(document).ready会起作用:

$(document).ready(function () {
  var imgs = $('#container img');
  jQuery.each(imgs, function() {
    $(this).replaceWith('<img src="timthumb/timthumb.php?src=' + $(this).attr('src') + '&w=200" />');
    });
});

但是原始未经调整大小的图像仍会在后台下载到浏览器的缓存中。是否有可能在客户端上做到我正在尝试的事情,还是只能在服务器端进行操作?


3
为什么不直接更改生成脚本中的源代码呢? - Scott A
3个回答

16
浏览器串行加载和执行JavaScript代码(除非你使用像head.js这样的工具),但问题是DOM必须在脚本修改它之前可用。jQuery的ready事件会在DOM可用后才触发,因此浏览器已经开始请求HTML中引用的资源。

如果将Javascript放在图片标签之前,它将无法找到图片标签,并且一旦ready事件触发,下载就已经开始了。我不知道是否有任何事件在图像加载之前触发(只有一个用于中止加载的事件),因此最简单的方法是在第一次创建HTML时就带有修改过的src属性。

或者,将src放在图像的另一个属性中(如data_orig_src),并在文档准备就绪时运行脚本,将src设置为data_orig_src。在更改src之前使用CSS隐藏图像,以便用户看不到损坏的图像标记。我认为这比事后添加图像要好,因为你不需要追踪图像需要放置在DOM中的位置,而且它应该也执行得更好。

当然,如果你可以更改服务器使用data_orig_src而不是src,那么为什么不直接在标签中放置正确的src呢?

好的,听起来似乎只有服务器端是可行的。谢谢。 - Toutouwai
我能想到的唯一原因你会这样做,就是你没有访问服务器代码的权限,或者由于某些原因修改它非常痛苦。 - Scott A
1
一个有效的用例示例是在类似Webflow的东西中实现背景图像的延迟加载。 - Tails
请注意,此答案已超过8年,世界已经发生了变化。 :-) 我们目前使用lazysizes(https://github.com/aFarkas/lazysizes)进行延迟加载图像。 - Scott A

8
在DOM加载之前,您不能更改页面的DOM。一旦DOM已经加载,浏览器已经开始请求图像。因此,在它们开始加载其图像之前,您无法更改标记。
您可以做的是更改页面的源代码,以便在页面的源代码中没有任何要更改的图像,然后在页面加载后使用JavaScript动态插入所需的图像。这样,浏览器就永远不会请求错误的图像。
或者,您可以将标签更改为根本没有src属性,并使用JavaScript添加.src属性。没有.src属性的标记不会显示,直到您提供.src属性为止。
如果您担心错误的图像在更改为正确的图像之前闪烁,您可以在样式表中使用CSS来最初隐藏图像,然后在更改img.src为正确值并加载新的.src值后,使它们可见。
如果您无法更改页面的源代码,则只能最初隐藏图像(使用CSS),直到已为它们设置了正确的.src,并且已加载了新的.src值。

关于隐藏图像,然后在事后更改img.src的注意事项是,您可能会遇到的一个问题是旧图像在新图像加载时会短暂地显示出来,因此您会得到一些“闪烁”效果。 - Highway of Life
最初隐藏图像的整个目的是不显示旧图像。 - jfriend00
没错,但如果你使用CSS进行隐藏,jQuery改变属性,然后显示图像,它会在新图像加载时闪现旧图像。 - Highway of Life
2
@HighwayofLife - 我测试了Safari、IE9和Chrome,都没有看到Flash。Firefox会出现Flash(多么虚假)。如果你想要防止Firefox中的Flash,可以在新图像加载时使用show()。这里有一个演示:http://jsfiddle.net/jfriend00/fgK9q/. - jfriend00

0

这是有可能的,但不是以你目前拥有或可能希望的方式,并且它不能优雅地降级,但你可以从你的HTML中取出图像,并使用jQuery将其插入到你的HTML中,并对其进行任何所需的更改。

示例:

var image = $('<img />').attr('src', 'imageURL.jpg');
image.appendTo('domElement');

但是这样做对我来说没有任何意义,为什么不直接编辑图像源呢。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接