Javascript 不要加载隐藏的图像
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3818063/
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
Don't load hidden images
提问by JoJo
I have a bunch of hidden images on my website. Their container DIVs have style="display: none". Depending on the user's actions, some images may be revealed via javascript. The problem is that all my images are loaded upon opening the page. I would like to put less strain on the server by only loading images that eventually become visible. I was wondering if there was a pure CSS way to do this. Here are two hacky/complicated ways I am currently doing it. As you can see, it's not clean code.
我的网站上有一堆隐藏的图片。他们的容器 DIV 有 style="display: none"。根据用户的操作,某些图像可能会通过 javascript 显示。问题是我所有的图片都是在打开页面时加载的。我想通过只加载最终变得可见的图像来减轻服务器的压力。我想知道是否有一种纯粹的 CSS 方式来做到这一点。这是我目前正在做的两种笨拙/复杂的方法。如您所见,这不是干净的代码。
<div id="hiddenDiv">
<img src="spacer.gif" />
</div>
.reveal .img {
background-image: url(flower.png);
}
$('hiddenDiv').addClassName('reveal');
Here is method 2:
这里是方法2:
<img id="flower" fakeSrc="flower.png" />
function revealImage(id) {
$('id').writeAttribute(
'src',
$('id').readAttribute('fakeSrc')
);
}
revealImage('flower');
回答by mekwall
The browser will load any images that has a src
attribute set, so what you want to do is to use data-src
in the markup and use JavaScript to set the src
attribute when you want it to load.
浏览器将加载具有src
属性集的任何图像,因此您要做的是data-src
在标记中使用并src
在您希望加载时使用 JavaScript 设置属性。
<img class="hidden" data-src="url/to/image.jpg" />
I created this tiny plugin that will take care of the problem:
我创建了这个小插件来解决这个问题:
(function($){
// Bind the function to global jQuery object.
$.fn.reveal = function(){
// Arguments is a variable which is available within all functions
// and returns an object which holds the arguments passed.
// It is not really an array, so by calling Array.prototype
// he is actually casting it into an array.
var args = Array.prototype.slice.call(arguments);
// For each elements that matches the selector:
return this.each(function(){
// this is the dom element, so encapsulate the element with jQuery.
var img = $(this),
src = img.data("src");
// If there is a data-src attribute, set the attribute
// src to make load the image and bind an onload event.
src && img.attr("src", src).load(function(){
// Call the first argument passed (like fadeIn, slideIn, default is 'show').
// This piece is like doing img.fadeIn(1000) but in a more dynamic way.
img[args[0]||"show"].apply(img, args.splice(1));
});
});
}
}(jQuery));
Execute .reveal
on the image(s) you want to load/show:
.reveal
在要加载/显示的图像上执行:
$("img.hidden").reveal("fadeIn", 1000);
请参阅jsFiddle 上的测试用例。
回答by Cristian Sanchez
Here's a jQuery solution:
这是一个jQuery解决方案:
$(function () {
$("img").not(":visible").each(function () {
$(this).data("src", this.src);
this.src = "";
});
var reveal = function (selector) {
var img = $(selector);
img[0].src = img.data("src");
}
});
It's similar to your solution, except it doesn't use the fakeSrc
attribute in the markup. It clears the src
attribute to stop it from loading and stores it elsewhere. Once you are ready to show the image, you use the reveal
function much like you do in your solution. I apologize if you do not use jQuery, but the process should be transferable to whichever framework (if any) that you use.
它类似于您的解决方案,只是它不使用fakeSrc
标记中的属性。它清除该src
属性以阻止它加载并将其存储在其他地方。准备好显示图像后,您可以reveal
像在解决方案中一样使用该功能。如果您不使用 jQuery,我深表歉意,但该过程应该可以转移到您使用的任何框架(如果有)。
Note: This code specifically must be ran before the window has fired the load
event but after the DOM has been loaded.
注意:此代码必须在窗口触发load
事件之前但在加载 DOM 之后运行。
回答by stevendesu
It partially depends on how your images must be placed in your code. Are you able to display the images as the background of a <div>, or are you required to use the <img> tag? If you need the <img> tag, you may be screwed depending on the browser being used. Some browsers are smart enough to recognize when an image is inside of a hidden object or in an object of 0 width/height and not load it since it's essentially invisible, anyway. For this reason many people will suggest putting an image in a 1x1 pixel <span> if you want the image to be pre-loaded but not visible.
这部分取决于您的图像必须如何放置在您的代码中。您是否能够将图像显示为 <div> 的背景,或者您是否需要使用 <img> 标签?如果你需要 <img> 标签,你可能会被使用的浏览器搞砸。一些浏览器足够聪明,可以识别图像何时位于隐藏对象内部或宽度/高度为 0 的对象中,并且不会加载它,因为它基本上是不可见的。出于这个原因,如果您希望图像被预加载但不可见,许多人会建议将图像放在 1x1 像素 <span> 中。
If you don't require the <img> tag, most browsers won't load images referenced by CSS until the element in question becomes visible.
如果您不需要 <img> 标签,大多数浏览器不会加载 CSS 引用的图像,直到相关元素变得可见。
Mind you that short of using AJAX to download the image there's no way to be 100% sure the browser won't pre-load the image anyway. It's not unbelievable that a browser would want to pre-load anything it assumes may be used later in order to "speed up" the average load times.
请注意,如果不使用 AJAX 下载图像,则无法 100% 确定浏览器无论如何都不会预加载图像。令人难以置信的是,浏览器想要预加载它认为以后可能会使用的任何东西,以“加快”平均加载时间。
回答by Alex Wayne
Using CSS to put the image an unused class, then adding that class to an element with javascript is going to be your best bet. If you don't use image tags at all, this solution becomes a bit more obvious.
使用 CSS 将图像放入一个未使用的类,然后将该类添加到使用 javascript 的元素将是您最好的选择。如果您根本不使用图像标签,则此解决方案会变得更加明显。
Though, for perspective, most people have the opposite problem where they want to preload an image so it shows up instantly when it's told to be shown.
不过,就角度而言,大多数人都有相反的问题,他们想要预加载图像,以便在被告知显示时立即显示。
回答by Terry
If you are okay relying on scripting, there is the background image method and the image src method. Put simply, set all your hidden images to some very small image (reduce strain on server) or one that does not exist at all (who cares? The visitor cannot see the image-missing [X] anyway, the div is hidden) then change it with script...
如果您可以依靠脚本编写,则可以使用背景图像方法和图像 src 方法。简而言之,将所有隐藏的图像设置为一些非常小的图像(减少服务器的压力)或根本不存在的图像(谁在乎?无论如何访问者都看不到图像缺失的 [X],div 被隐藏了)然后用脚本改变它...
<img src="I_do_not_exist.jpg" id="my_image" />
<input type="button" onclick="document.getElementById('my_image').src='I_exist.jpg';" Value="change image" />
<br /><br /><br />
<div id="mydiv" style="width:40px; height:40px; border:2px solid blue"></div>
<input type="button" onclick="document.getElementById('my_div').style.width='455px';document.getElementById('my_div').style.height='75px';document.getElementById('my_div').style.backgroundImage='url(I_exist.jpg)';" Value="change background image" />
I left a width on the above example to show that nothing is in the div image wise until you ask it to load.
我在上面的示例中留下了一个宽度,以表明在您要求加载之前,div 图像中没有任何内容。
回答by ats
如果在 CSS 中将图像设为 div 的背景图像,当该 div 设置为“显示:无”时,图像将不会加载。
You can do the following for a pure CSS solution, it also makes the img box actually behave like an img box in a responsive design setting (that's what the transparent png is for), which is especially useful if your design uses responsive-dynamically-resizing images.
您可以为纯 CSS 解决方案执行以下操作,它还使 img 框实际上表现得像响应式设计设置中的 img 框(这就是透明 png 的用途),如果您的设计使用响应式动态,这尤其有用-调整图像大小。
<img style="display: none; height: auto; width:100%; background-image:
url('img/1078x501_1.jpg'); background-size: cover;" class="center-block
visible-lg-block" src="img/400x186_trans.png" alt="pic 1">
The image will only be loaded when the media query tied to visible-lg-block is triggered and display:none is changed to display:block. The transparent png is used to allow the browser to set appropriate height:width ratios for your <img> block (and thus the background-image) in a fluid design (height: auto; width: 100%).
仅当与visible-lg-block 绑定的媒体查询被触发并且display:none 更改为display:block 时才会加载图像。透明 png 用于允许浏览器在流体设计(高度:自动;宽度:100%)中为 <img> 块(以及背景图像)设置适当的高度:宽度比率。
1078/501 = ~2.15 (large screen)
400/186 = ~2.15 (small screen)
So you end up with something like the following, for 3 different viewports:
因此,对于 3 个不同的视口,您最终会得到如下结果:
<img style="display: none; height: auto; width:100%; background-image: url('img/1078x501_1.jpg'); background-size: cover;" class="center-block visible-lg-block" src="img/400x186_trans.png" alt="pic 1">
<img style="display: none; height: auto; width:100%; background-image: url('img/517x240_1.jpg'); background-size: cover;" class="center-block visible-md-block" src="img/400x186_trans.png" alt="pic 1">
<img style="display: none; height: auto; width:100%; background-image: url('img/400x186_1.jpg'); background-size: cover;" class="center-block visible-sm-block" src="img/400x186_trans.png" alt="pic 1">
And only your default media viewport size images load during the initial load, then afterwards, depending on your viewport, images will dynamically load.
并且仅在初始加载期间加载默认媒体视口大小的图像,然后根据您的视口,图像将动态加载。
And no javascript!
而且没有javascript!