Html 异步加载图片
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15999760/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
load image asynchronous
提问by amateur
If I have an image tag like the following:
如果我有一个像下面这样的图像标签:
<img src="myimage.jpg" />
and if I add "async" to it:
如果我向它添加“异步”:
<img async src="myimage.jpg" />
will the image load asynchronous?
图片会异步加载吗?
回答by patrick
The way to async load (lazy load) the content is to not set the 'src' attribute and then execute a script that loads the images once DOM-ready is launched.
异步加载(延迟加载)内容的方法是不设置 'src' 属性,然后在启动 DOM-ready 后执行加载图像的脚本。
<img data-lazysrc='http://www.amazingjokes.com/images/20140902-amazingjokes-title.png'/>
and with jQuery (or possible with plain JavaScript too) use below code (as suggested here):
并与jQuery(或可能与普通的JavaScript太)下面的代码使用(如建议在这里):
<script>
function ReLoadImages(){
$('img[data-lazysrc]').each( function(){
//* set the img src from data-src
$( this ).attr( 'src', $( this ).attr( 'data-lazysrc' ) );
}
);
}
document.addEventListener('readystatechange', event => {
if (event.target.readyState === "interactive") { //or at "complete" if you want it to execute in the most last state of window.
ReLoadImages();
}
});
</script>
回答by Norguard
var img = new Image(),
url = "myimg.jpg",
container = document.getElementById("holder-div");
img.onload = function () { container.appendChild(img); };
img.src = url;
This would start loading an image as soon as you request it in-script, and whenever the image was done loading, it would grab and add the image to it.
这将在您在脚本中请求图像时立即开始加载图像,并且每当图像加载完成时,它就会抓取图像并将其添加到其中。
There are lots of other ways of doing this...
This is just a dead-simple example of async loading of a single image.
有很多其他方法可以做到这一点......
这只是异步加载单个图像的一个非常简单的例子。
But the moral is this:
For async loading to work, either load it in JavaScript and use the onload, or include the image tag on the page, without the src
attribute (specify the width
and height
in HTML), and go back at some point, in JS, and set the image URL.
但道德是这样的:
为了异步加载工作,要么在 JavaScript 中加载它并使用 onload,要么在页面上包含图像标记,不带src
属性(在 HTML 中指定width
and height
),然后在某个时候返回,在JS,并设置图片网址。
回答by anekix
I See a lot of answers here using Jquery
or some library
just to do this simple task.This can be done using Promise
in javascripts which serves the purpose of doing things asynchronously.
我在这里看到很多答案使用Jquery
或一些library
只是为了完成这个简单的任务Promise
。这可以在 javascripts 中使用来完成,它用于异步做事。
function asyncImageLoader(url){
return new Promise( (resolve, reject) => {
var image = new Image()
image.src = url
image.onload = () => resolve(image)
image.onerror = () => reject(new Error('could not load image'))
})
}
// then use it like this
var image = asyncImageLoader(url)
image.then( res => {
console.log(res)
})
回答by mpm
<img async src="myimage.jpg" />
The image tag doesnt supports any async attribute.
图像标签不支持任何异步属性。
http://www.w3.org/TR/html5/embedded-content-0.html#the-img-element
http://www.w3.org/TR/html5/embedded-content-0.html#the-img-element
回答by Fenton
There is currently an open pull request with the WHATWG to introduce the loading
attribute for images and iframes.
目前 WHATWG 有一个开放的拉取请求来引入loading
图像和 iframe的属性。
Loading=Lazy
加载=懒惰
This will defer loading of the content until the element reaches a calculated distance from the viewport (that just means, it's got quite likely that the user will scroll it into view).
这将推迟内容的加载,直到元素到达与视口的计算距离(这只是意味着,用户很可能会将其滚动到视图中)。
<img src="defer.png" loading="lazy" alt="An Awesome Image" width="500" height="400">
Setting the attribute to lazy
invokes the new behaviour.
将属性设置为lazy
调用新行为。
This is already in Chromium since v76, but might not hit non-Chromium browsers until it goes through the usual specification shennanigans.
自 v76 以来,这已经在 Chromium 中,但在通过通常的规范恶作剧之前,它可能不会影响非 Chromium 浏览器。
If you are going to defer loading using a script, it would be worth writing the image with the lazy
attribute and polyfilling the behavior as opposed to working off of a class name, etc. That way, you can allow the native version to take over as it becomes available.
如果您打算使用脚本延迟加载,那么值得使用lazy
属性编写图像并填充行为,而不是使用类名等。这样,您可以允许本机版本作为它变得可用。
Forced Eager Loading
强制加载
Automatic lazy loading may become a feature of lightweight browsing, in which case, you may want to do the inverse and force an image to load. You can use the same loading
attribute with a value of eager
to ask the browser to grab the image even if it might otherwise choose not to.
自动延迟加载可能会成为轻量级浏览的一个特性,在这种情况下,您可能需要做相反的事情并强制加载图像。您可以使用loading
值为的相同属性eager
来要求浏览器抓取图像,即使它可能会选择不抓取。
<img src="defer.png" loading="eager" alt="An Awesome Image" width="500" height="400">
Further reading
进一步阅读
View the pull request for the WHATWG spec
Fallback JavaScript with notes about perhaps not using fallbacks
回答by derekbaker783
While several other answers highlight ways to fetch images asynchronously, it may also be helpful to know that the <img />
tag supports an attribute that serves as a hintto the browser that mayresult in images being be decoded asynchronously. It doesn't appear to be supported by Internet Explorer.
虽然其他几个答案强调了异步获取图像的方法,但了解该<img />
标签支持作为浏览器提示的属性可能会导致图像被异步解码,这也可能会有所帮助。Internet Explorer 似乎不支持它。
<img src="myimage.jpg" decoding="async"/>
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Img#attr-decoding
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Img#attr-decoding
https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/decoding
https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/decoding
回答by John Washam
If you're using jQuery, I did something simple, yet effective, like this:
如果您使用 jQuery,我做了一些简单但有效的事情,如下所示:
HTML
HTML
<div data-lazy-load-image="/Images/image-name.png" data-image-classname="pop-in"></div>
JavaScript
JavaScript
$(function () {
$("[data-lazy-load-image]").each(function (index, element) {
var img = new Image();
img.src = $(element).data("lazy-load-image");
if (typeof $(element).data("image-classname" !== "undefined"))
img.className = $(element).data("image-classname");
$(element).append(img);
});
});
CSS
CSS
@-webkit-keyframes pop-in {
0% { opacity: 0; -webkit-transform: scale(0.5); }
100% { opacity: 1; -webkit-transform: scale(1); }
}
@-moz-keyframes pop-in {
0% { opacity: 0; -moz-transform: scale(0.5); }
100% { opacity: 1; -moz-transform: scale(1); }
}
@keyframes pop-in {
0% { opacity: 0; transform: scale(0.5); }
100% { opacity: 1; transform: scale(1); }
}
You could extend this to include additional optional attributes for each image, but you get the idea.
您可以扩展它以包含每个图像的附加可选属性,但您明白了。
This will wait until the DOM is ready, then dynamically (async) load the images into the element that you mark with the data-lazy-load-image
attribute. I included the CSS to make the images "pop in" when they are loaded.
这将等到 DOM 准备就绪,然后动态(异步)将图像加载到您使用该data-lazy-load-image
属性标记的元素中。我包含了 CSS 以使图像在加载时“弹出”。
回答by Victor H?ggqvist
While @Norguard's example is quite simple and easy enought for an image or two, I have found echo.js pretty handy for lazy-loading, https://github.com/toddmotto/echo.
虽然@Norguard 的例子对于一两个图像来说非常简单和容易,但我发现 echo.js 对于延迟加载非常方便,https://github.com/toddmotto/echo。
It does lazy-loading images with data-* attributes and comes with some neat other things too.
它使用 data-* 属性延迟加载图像,并且还带有一些整洁的其他东西。
<img data-echo="img/photo.jpg">
<script src="dist/echo.js"></script>
<script>
echo.init();
</script>
回答by Deke
I have used the following approach with jQuery.
我在 jQuery 中使用了以下方法。
First, don't use a "src" attribute in the image tag, but put your source into a different attribute, like this:
首先,不要在图像标签中使用“src”属性,而是将您的源放入不同的属性中,如下所示:
<img async-src="/mydirectory/myimage.jpg" />
Then, within the jQuery document-ready function, I use this code to copy the element's async-src to the element's actual src:
然后,在 jQuery 文档就绪函数中,我使用此代码将元素的 async-src 复制到元素的实际 src:
$("img[async-src]").each(function(index) {
$(this).attr("src", $(this).attr("async-src"));
});
Notes:
笔记:
jQuery's .each function may process the tags in the sequence they are coded in the HTML/DOM, but image sizes and network issues may mean that images don't actually loadsequentially. In other words, your third async-src image might visually appear onscreen before the first has finished loading.
jQuery 的 .each 函数可能会按照在 HTML/DOM 中编码的顺序处理标签,但是图像大小和网络问题可能意味着图像实际上并不是按顺序加载的。换句话说,您的第三个 async-src 图像可能会在第一个完成加载之前直观地出现在屏幕上。
If your page layout relies on the pixel dimensions of that image file — e.g. you're not defining the image's dimensions via tag attributes, CSS, or a parent element — then you may have to use a "src" attribute on the original file pointing to a blank white or clear GIF of the dimensions you want.
如果您的页面布局依赖于该图像文件的像素尺寸——例如,您没有通过标签属性、CSS 或父元素定义图像的尺寸——那么您可能必须在原始文件上使用“src”属性指向到您想要的尺寸的空白或清晰的 GIF。
Finally, if you want to process some code after the async loading of the image — for example, to handle a fading effect or change a CSS tag relevant to the element — expand the jQuery like this:
最后,如果你想在异步加载图像后处理一些代码——例如,处理淡入淡出效果或更改与元素相关的 CSS 标签——像这样扩展 jQuery:
$("img[async-src]").each(function(index) {
$(this).load(function() {
// code to run after loading
});
$(this).attr("src", $(this).attr("async-src"));
});
回答by Miroslav ?i?ka
You can read more about lazyload attribute:
您可以阅读有关lazyload 属性的更多信息:
<img src="myimage.jpg" alt="some description" lazyload/> - with default values
or you can prioritize:
或者您可以优先考虑:
<img src="myimage.jpg" alt="some description" lazyload="1"/>
<img src="myimage.jpg" alt="some description" lazyload="2"/>