최근 자바스크립트를 사용하여 애니메이션 기능을 만들고 싶습니다. 애니메이션이 원활하게 재생되도록 하려면 사용된 이미지 자료를 미리 로드해야 합니다. 이 기능을 구현하는 과정을 알려드리겠습니다.
단일 이미지 사전 로드
현재 가장 일반적인 구현 방법은 다음과 같습니다
function preloadImg(url) { var img = new Image(); img.src = url; if(img.complete) { //接下来可以使用图片了 //do something here } else { img.onload = function() { //接下来可以使用图片了 //do something here }; } }
먼저 Image 개체를 인스턴스화하여 img에 할당한 다음 img.src를 매개변수 url로 지정된 이미지 주소로 설정한 다음 img의 전체 속성을 확인합니다. 이 때 해당 이미지의 로컬 캐시가 있으면 값이 true입니다. 로컬 캐시가 없으면 값이 false입니다. img의 onload 이벤트를 수신하고 img의 작업을 onload 콜백 함수에 변경해야 합니다. 테스트 후 이 솔루션은 기본적으로 모든 현재 브라우저와 호환됩니다.
다중 이미지 사전 로드
많은 시나리오에서 단일 애니메이션과 같은 기능에는 일반적으로 그림 자료가 많기 때문에 이미지 미리 로드는 우리의 요구를 충족할 수 없습니다. 다음으로, 원본 단일 그림 미리 로드를 기반으로 기능을 개선하겠습니다
function preloadImg(list) { var imgs = arguments[1] || [], //用于存储预加载好的图片资源 fn = arguments.cal lee; if(list.length == 0) { return imgs; } var img = new Image(); img.src = list[0]; if(img.complete) { imgs.push(img); list.shift(); fn(list, imgs); } else { img.onload = function() { imgs.push(img); list.shift(); fn(list, imgs); }; } } var list = [......], //此处省略一万个字符 imgs = preloadImg();
프레임 애니메이션은 사용된 그림의 순서를 보장해야 할 수 있습니다. 따라서 이 코드에서는 재귀를 사용하여 이전 사진이 로드된 후 다음 사진을 로드합니다. 사진이 로드될 때마다 사진 리소스는 imgs 배열에 저장되고 사진의 주소는 제거됩니다. 주소 배열 목록에서 목록에 주소가 없으면 재귀에서 벗어나 imgs 배열을 반환합니다
아이디어는 아름답고 현실은 잔혹합니다. 이 코드에는 두 가지 참을 수 없는 문제가 있습니다
우선, 저는 로컬로 캐시되지 않은 사진이 있는 한 imgs의 저장 작업은 onload 콜백 이벤트에 배치되고 이벤트 모니터링도 JavaScript의 비동기 작업 유형이기 때문에 마지막으로 반환된 imgs 배열을 가져올 수 없습니다. . onload 이벤트 바인딩 후 콜백 함수 이후 preloadImg 함수는 반환 값 없이 종료됩니다. 외부 imgs 변수에 의해 수신된 값은 정의되지 않습니다. 모든 사진에 로컬 캐시가 있는 경우에만 외부 imgs 변수가 사전 로드된 모든 이미지를 성공적으로 얻을 수 있습니다. . 이미지 리소스 배열 로드
다음 이미지를 로드하기 전에 하나의 이미지를 로드한 후 이미지를 미리 로드하는 전체 프로세스는 상대적으로 오랜 시간이 걸리고 사용자 경험이 줄어들며 비동기 작업이 본질적으로 빠릅니다. 이는 onload 비동기 기능을 완전히 포기하는 것과 같습니다
다중 이미지 미리 로드(개선된 버전)
이번에는 빈 배열을 함수에 매개변수로 직접 전달하고 모든 이미지가 이 배열에 저장됩니다. 개선된 함수 코드(jQuery를 사용할 수 있다고 가정)
function preloadImg(list,imgs) { var def = $.Deferred(), len = list.length; $(list).each(function(i,e) { var img = new Image(); img.src = e; if(img.complete) { imgs[i] = img; len--; if(len == 0) { def.resolve(); } } else { img.onload = (function(j) { return function() { imgs[j] = img len--; if(len == 0) { def.resolve(); } }; })(i); img.onerror = function() { len--; console.log('fail to load image'); }; } }); return def.promise(); } var list = [......], //此处省略一万个字符 imgs = []; $.when(preloadImg(list, imgs)).done( function() { //预加载结束 //do something here } );
는 onload 콜백 함수를 각 img에 각각 바인딩할 때 클로저 메서드를 사용합니다. 목적은 현재 증분 변수 i를 저장하는 것입니다. 그렇지 않으면 결과는 다음과 같습니다. 로컬에 캐시되지 않은 목록 주소의 모든 사진은 imgs의 마지막 요소에 저장됩니다
이번에는 사진이 로드될 때마다 목록 배열에서 이 사진의 주소를 제거하지 않습니다. 나중에 목록 배열의 데이터를 사용해야 할 때 성공적으로 얻을 수 있습니다
이 코드에서는 jQuery의 Deferred 개체를 도입하여 이미지를 미리 로드하는 전체 과정을 더 쉽게 파악할 수 있습니다
위 내용은 jQuery가 사전 로딩 이미지 기능을 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!