JavaScript를 사용한 이미지 프리로드
아래에 기재한 기능은 현재 일반적으로 사용되는 브라우저의 전부는 아니지만 대부분 이미지를 프리로드할 수 있는 기능입니까?
function preloadImage(url)
{
var img=new Image();
img.src=url;
}
, 이 배열을 「URL」, 「URL」이라고 .preloadImage
기능을 합니다.
네. 이 기능은 모든 주요 브라우저에서 작동합니다.
이거 먹어봐 이게 더 나은 것 같아.
var images = [];
function preload() {
for (var i = 0; i < arguments.length; i++) {
images[i] = new Image();
images[i].src = preload.arguments[i];
}
}
//-- usage --//
preload(
"http://domain.tld/gallery/image-001.jpg",
"http://domain.tld/gallery/image-002.jpg",
"http://domain.tld/gallery/image-003.jpg"
)
출처 : http://perishablepress.com/3-ways-preload-images-css-javascript-ajax/
이 코드를 index.html로 이동하여 임의의 URL에서 이미지를 프리로드할 수 있습니다.
<link rel="preload" href="https://via.placeholder.com/160" as="image">
, ''을 '으로 함수에 콜백을 추가해 .onload
이벤트 표시:
function preloadImage(url, callback)
{
var img=new Image();
img.src=url;
img.onload = callback;
}
그런 다음 모든 콜백에서 프리로드되는 이미지에 URL 배열이 있을 경우 랩합니다.https://jsfiddle.net/4r0Luoy7/
function preloadImages(urls, allImagesLoadedCallback){
var loadedCounter = 0;
var toBeLoadedNumber = urls.length;
urls.forEach(function(url){
preloadImage(url, function(){
loadedCounter++;
console.log('Number of loaded images: ' + loadedCounter);
if(loadedCounter == toBeLoadedNumber){
allImagesLoadedCallback();
}
});
});
function preloadImage(url, anImageLoadedCallback){
var img = new Image();
img.onload = anImageLoadedCallback;
img.src = url;
}
}
// Let's call it:
preloadImages([
'//upload.wikimedia.org/wikipedia/commons/d/da/Internet2.jpg',
'//www.csee.umbc.edu/wp-content/uploads/2011/08/www.jpg'
], function(){
console.log('All images were loaded');
});
const preloadImage = src =>
new Promise((resolve, reject) => {
const image = new Image()
image.onload = resolve
image.onerror = reject
image.src = src
})
// Preload an image
await preloadImage('https://picsum.photos/100/100')
// Preload a bunch of images in parallel
await Promise.all(images.map(x => preloadImage(x.src)))
CSS2 대체: http://www.thecssninja.com/css/even-better-image-preloading-with-css2
body:after {
content: url(img01.jpg) url(img02.jpg) url(img03.jpg);
display: none;
}
CSS3 대체: https://perishablepress.com/preload-images-css3/ (H/T Linh Dam)
.preload-images {
display: none;
width: 0;
height: 0;
background: url(img01.jpg),
url(img02.jpg),
url(img03.jpg);
}
컨테이너 에는 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★display:none
프리로드되지 않을 수 있습니다.가시성: 숨김이 더 잘 작동하지만 아직 테스트하지 않았습니다.이 이 점을 해 주셔서 합니다.Marco Del Valle 。
발생할 수 있는 문제를 방지하기 위해 try/catch를 사용할 것을 권장합니다.
OOP:
var preloadImage = function (url) {
try {
var _img = new Image();
_img.src = url;
} catch (e) { }
}
표준:
function preloadImage (url) {
try {
var _img = new Image();
_img.src = url;
} catch (e) { }
}
또, 저는 DOM을 좋아하지만, 오래된 멍청한 브라우저는 DOM을 사용하는 것에 문제가 있을 수 있으므로, freedev의 기고와는 반대로 IMHO는 피하십시오.Image()는 오래된 휴지통 브라우저에서 더 나은 지원을 제공합니다.
이 방법은 조금 더 정교합니다.여기에서는 미리 로드된 모든 영상을 용기에 저장합니다(div).그리고 영상을 표시하거나 DOM 내에서 올바른 위치로 이동할 수 있습니다.
function preloadImg(containerId, imgUrl, imageId) {
var i = document.createElement('img'); // or new Image()
i.id = imageId;
i.onload = function() {
var container = document.getElementById(containerId);
container.appendChild(this);
};
i.src = imgUrl;
}
여기서 사용해 보세요.저도 몇 가지 코멘트를 덧붙였습니다.
2020년 현재 운용 중인 솔루션
이 게시물의 대부분의 답변이 작동하지 않습니다(최소한 Firefox에서는).
제 해결책은 다음과 같습니다.
var cache = document.createElement("CACHE");
cache.style = "position:absolute;z-index:-1000;opacity:0;";
document.body.appendChild(cache);
function preloadImage(url) {
var img = new Image();
img.src = url;
img.style = "position:absolute";
cache.appendChild(img);
}
사용방법:
preloadImage("example.com/yourimage.png");
론. 뻔. obviously. obviously.<cache>
'정의된' 요소를 할 수 .<div>
신신면면면면면면면
를 에, 을 CSS 로 해 .style
★★★★
cache {
position: absolute;
z-index: -1000;
opacity: 0;
}
cache image {
position: absolute;
}
테스트하셨다면 댓글로 남겨주세요.
주의:
- 안 함
display: none;
캐시하기 - 이미지를 로드하지 않습니다. - 이미지 요소의 크기를 조정하지 마십시오. 사용할 때 로드된 이미지의 품질에도 영향을 미칩니다.
- ★★
position: absolute
이미지 요소가 결국 뷰포트를 벗어나 로드되지 않고 성능에 영향을 미치기 때문에 이미지 요소가 반드시 필요합니다.
갱신하다
위의 솔루션이 동작하는 동안 이를 적절하게 구성하기 위해 다음과 같이 업데이트했습니다.
(이것도 하나의 기능으로 여러 이미지를 사용할 수 있게 되었습니다.)
var cache = document.createElement("CACHE");
document.body.appendChild(cache);
function preloadImage() {
for (var i=0; i<arguments.length; i++) {
var img = new Image();
img.src = arguments[i];
var parent = arguments[i].split("/")[1]; // Set to index of folder name
if ($(`cache #${parent}`).length == 0) {
var ele = document.createElement("DIV");
ele.id = parent;
cache.appendChild(ele);
}
$(`cache #${parent}`)[0].appendChild(img);
console.log(parent);
}
}
preloadImage(
"assets/office/58.png",
"assets/leftbutton/124.png",
"assets/leftbutton/125.png",
"assets/leftbutton/130.png",
"assets/leftbutton/122.png",
"assets/leftbutton/124.png"
);
미리 보기:
주의:
- 동시에 너무 많은 이미지가 프리로드된 상태로 유지되지 않도록 주의해 주세요(이것은 큰 퍼포먼스 문제를 일으킬 수 있습니다).특정 이벤트 중에는 표시되지 않을 것으로 생각되는 이미지를 숨김으로써 이 문제를 회피할 수 있었습니다.그럼 당연히 필요할 때 다시 보여줘야죠.
ECMAScript 2017 준거 브라우저용 솔루션
주의: Babel과 같은 트랜스필러를 사용하는 경우에도 사용할 수 있습니다.
'use strict';
function imageLoaded(src, alt = '') {
return new Promise(function(resolve) {
const image = document.createElement('img');
image.setAttribute('alt', alt);
image.setAttribute('src', src);
image.addEventListener('load', function() {
resolve(image);
});
});
}
async function runExample() {
console.log("Fetching my cat's image...");
const myCat = await imageLoaded('https://placekitten.com/500');
console.log("My cat's image is ready! Now is the time to load my dog's image...");
const myDog = await imageLoaded('https://placedog.net/500');
console.log('Whoa! This is now the time to enable my galery.');
document.body.appendChild(myCat);
document.body.appendChild(myDog);
}
runExample();
모든 이미지가 로드될 때까지 기다릴 수도 있습니다.
async function runExample() {
const [myCat, myDog] = [
await imageLoaded('https://placekitten.com/500'),
await imageLoaded('https://placedog.net/500')
];
document.body.appendChild(myCat);
document.body.appendChild(myDog);
}
「」를 사용합니다.Promise.all
병렬로 적재할 수 있습니다.
async function runExample() {
const [myCat, myDog] = await Promise.all([
imageLoaded('https://placekitten.com/500'),
imageLoaded('https://placedog.net/500')
]);
document.body.appendChild(myCat);
document.body.appendChild(myDog);
}
"Async" 기능에 대한 자세한 정보
ECMAScript 2015에 대한 자세한 정보
ECMAScript 2017에 대한 자세한 정보
HTML Living Standard가 '프리로드'를 지원하게 되었습니다.
W3C HTML 사양에 따르면 다음과 같이 JavaScript를 사용하여 프리로드할 수 있습니다.
var link = document.createElement("link");
link.rel = "preload";
link.as = "image";
link.href = "https://example.com/image.png";
document.head.appendChild(link);
저의 접근방식은 다음과 같습니다.
var preloadImages = function (srcs, imgs, callback) {
var img;
var remaining = srcs.length;
for (var i = 0; i < srcs.length; i++) {
img = new Image;
img.onload = function () {
--remaining;
if (remaining <= 0) {
callback();
}
};
img.src = srcs[i];
imgs.push(img);
}
};
헤드의 링크 태그를 사용하면 브라우저가 가장 잘 작동합니다.
export function preloadImages (imageSources: string[]): void {
imageSources
.forEach(i => {
const linkEl = document.createElement('link');
linkEl.setAttribute('rel', 'preload');
linkEl.setAttribute('href', i);
linkEl.setAttribute('as', 'image');
document.head.appendChild(linkEl);
});
}
네, 이것은 동작합니다만, 브라우저는 실제 콜을 제한(4~8개)하기 때문에, 필요한 이미지를 모두 캐시/프리로드 하는 것은 아닙니다.
이미지를 사용하기 전에 onload를 호출하는 것이 더 좋은 방법입니다.
function (imageUrls, index) {
var img = new Image();
img.onload = function () {
console.log('isCached: ' + isCached(imageUrls[index]));
*DoSomething..*
img.src = imageUrls[index]
}
function isCached(imgUrl) {
var img = new Image();
img.src = imgUrl;
return img.complete || (img .width + img .height) > 0;
}
질문의 접근법이 적어도 다음 중 하나에서 이미지 다운로드 및 캐시(응답 헤더를 통해 브라우저가 다운로드 및 캐시하는 것을 금지하지 않는 한)를 트리거하기에 충분한지 확인할 수 있습니다.
- 크롬 74
- 사파리 12
- 파이어폭스 66
- 엣지 17
이를 테스트하기 위해 각각 10초씩 잠을 자는 여러 개의 끝점이 있는 작은 웹 앱을 만들어 고양이 사진을 제공했습니다. 두 웹 페이지를 했는데, 그 중한 페이지에는 '하다'라는 웹 페이지가 되어 있습니다.<script>
preloadImage
질문에서 기능하며, 다른 질문에는 페이지 상의 모든 아기 고양이가 포함됩니다.<img>
모든 프리로더 을 알 수 있었습니다.<img>
그,, 내내내내은은은은은은은즉즉즉즉즉즉.이는 프리로더가 테스트된 모든 브라우저에서 성공적으로 아기 고양이를 캐시에 로드했음을 나타냅니다.
테스트에 사용한 어플리케이션은 https://github.com/ExplodingCabbage/preloadImage-test 에서 확인하실 수 있습니다.
특히 이 기법은 Robin의 답변과는 달리 루프오버되는 이미지의 수가 브라우저가 한 번에 실행할 수 있는 병렬 요구 수를 초과하더라도 위의 브라우저에서 작동합니다.이미지 프리로드 속도는 물론 브라우저가 송신할 병렬 요청 수에 따라 제한되지만 최종적으로 호출하는 각 이미지 URL이 요구됩니다.preloadImage()
켜집니다.
내가 한 일은 다음과 같다.
const listOfimages = [
{
title: "something",
img: "https://www.somewhere.com/assets/images/someimage.jpeg"
},
{
title: "something else",
img: "https://www.somewhere.com/assets/images/someotherimage.jpeg"
}
];
const preload = async () => {
await Promise.all(
listOfimages.map(
(a) =>
new Promise((res) => {
const preloadImage = new Image();
preloadImage.onload = res;
preloadImage.src = a.img;
})
)
);
}
이것은 원래의 답변이지만 보다 현대적인 ES 구문을 사용한 것입니다.
let preloadedImages = [];
export function preloadImages(urls) {
preloadedImages = urls.map(url => {
let img = new Image();
img.src = url;
img.onload = () => console.log(`image url [${url}] has been loaded successfully`);
return img;
});
}
OP에서 제공하는 코드에 대한 몇 가지 대안을 소개합니다.
preloadImage()
함수가 반환되었습니다.
function preloadImage = function(url){
const img = new Image();
img.src = url;
return img
}
v1: 이미지를 인수로 전달하여 프리로드preloadImages()
의 배열을 반환합니다.Image
함수에서 반환된 입력된 개체입니다.프리로드 상태를 확인할 때 유용합니다.
function preloadImage(url){
const img = new Image();
img.src = url;
return img
}
function preloadImages() {
const images = []
for (var i = 0; i < arguments.length; i++) {
images[i] = preloadImage(arguments[i])
}
return images
}
//-- usage --//
const images = preloadImages(
"http://domain.tld/gallery/image-001.jpg",
"http://domain.tld/gallery/image-002.jpg",
"http://domain.tld/gallery/image-003.jpg"
)
v2: 이미지를 어레이로 전달하여 프리로드preloadImages()
Not type safe 지정된 어레이를 덮어씁니다.Image
type object를 입력합니다.의 배열을 반환합니다.Image
이치노이치노
function preloadImage(url){
const img = new Image();
img.src = url;
return img
}
function preloadImages(images) {
for (var i = 0; i < images.length; i++) {
images[i] = preloadImage(images[i])
}
return images
}
//-- usage --//
let arr = [
"http://domain.tld/gallery/image-001.jpg",
"http://domain.tld/gallery/image-002.jpg",
"http://domain.tld/gallery/image-003.jpg"
]
const images = preloadImages(arr)
console.dir(images)
v3: 어레이 및/또는 인수를 전달하여 프리로드preloadImages()
safe 라고 입력합니다.의 배열을 반환합니다.Image
이치노이치노
function preloadImage(url){
const img = new Image();
img.src = url;
return img
}
function preloadImages() {
const images = []
let c = 0
for (var i = 0; i < arguments.length; i++) {
if (Array.isArray(arguments[i])) {
for(var arr = 0; arr < arguments[i].length; arr++) {
if(typeof arguments[i][arr] == 'string') {
images[c] = preloadImage(arguments[i][arr])
c++
}
}
}
else if(typeof arguments[i] == 'string') {
images[c] = preloadImage(arguments[i])
c++
}
}
return images
}
//-- usage --//
var arr = [
"http://domain.tld/gallery/image-001.jpg",
"http://domain.tld/gallery/image-002.jpg"
]
const images = preloadImages(
arr,
"http://domain.tld/gallery/image-003.jpg",
"http://domain.tld/gallery/image-004.jpg",
[
"http://domain.tld/gallery/image-005.jpg",
"http://domain.tld/gallery/image-006.jpg"
]
)
console.dir(images)
영감: http://perishablepress.com/3-ways-preload-images-css-javascript-ajax/
언급URL : https://stackoverflow.com/questions/3646036/preloading-images-with-javascript
'programing' 카테고리의 다른 글
PHP에서 어레이와 데이터를 정렬하려면 어떻게 해야 합니까? (0) | 2023.01.31 |
---|---|
PHP를 사용하여 JQuery .ajax()에 대한 적절한 성공/오류 메시지를 반환하려면 어떻게 해야 합니까? (0) | 2023.01.31 |
SELECT 내에서 여러 CASE 콜을 심플화 (0) | 2023.01.31 |
PHPUnit: 두 어레이가 동일하지만 요소의 순서는 중요하지 않습니다. (0) | 2023.01.31 |
SoapClient 클래스를 사용하여 PHP SOAP 호출을 발신하는 방법 (0) | 2023.01.31 |