Avant-propos
Imagepool est un outil JS pour gérer le chargement des images. Imagepool peut contrôler le nombre d'images chargées simultanément.
Pour le chargement d'images, la manière la plus primitive est d'écrire directement une balise img, telle que : .
Après une optimisation continue, une solution de chargement paresseux pour les images a émergé. Cette fois, l'URL de l'image n'est pas écrite directement dans l'attribut src, mais dans un certain attribut, tel que : . De cette façon, le navigateur ne chargera pas automatiquement l'image lorsqu'elle doit être chargée à un moment approprié, utilisez js pour placer l'url de l'attribut data-src dans l'attribut src de la balise img, ou après avoir lu l'url. , utilisez js pour charger l'image, définissez l'attribut src une fois le chargement terminé et affichez l'image.
Cela semble être bien contrôlé, mais il reste encore des problèmes.
Bien qu'il soit possible de charger seulement une partie de l'image, cette partie de l'image peut néanmoins représenter un ordre de grandeur relativement important.
Ce n'est pas bien grave côté PC, mais côté mobile, trop d'images sont chargées simultanément, ce qui risque très probablement de provoquer un crash de l'application.
Par conséquent, nous avons besoin de toute urgence d’un mécanisme de mise en mémoire tampon d’image pour contrôler la simultanéité du chargement des images. Semblable au pool de connexions à la base de données principale, il ne créera pas trop de connexions et pourra réutiliser entièrement chaque connexion.
À ce stade, imagepool est né.
Mauvais schéma
Mode d'emploi
Vous devez d'abord initialiser le pool de connexions :
var imagepool = initImagePool(5);
initImagePool est une méthode globale et peut être utilisée directement n'importe où. La fonction consiste à créer un pool de connexions et vous pouvez spécifier le nombre maximum de connexions dans le pool de connexions, facultatif, et la valeur par défaut est 5.
Dans la même page, appeler initImagePool plusieurs fois renverra la même instance principale, toujours la première, ce qui ressemble un peu à un singleton. Par exemple :
var imagepool1 = initImagePool(3);
var imagepool2 = initImagePool(7);
À l'heure actuelle, le nombre maximum de connexions pour imagepool1 et imagepool2 est de 3, et la même instance principale est utilisée en interne. Notez que les cœurs internes sont les mêmes, pas que imagepool1 === imagepool2.
Après l'initialisation, vous pouvez charger des images en toute confiance.
La méthode d'appel la plus simple est la suivante :
var imagepool = initImagePool(10);
imagepool.load("url de l'image",{
Succès : fonction(src){
console.log("success:::::" src);
},
erreur : fonction(src){
console.log("erreur:::::" src);
>
});
Appelez simplement la méthode load directement sur l’instance.
La méthode de chargement a deux paramètres. Le premier paramètre est l'URL de l'image qui doit être chargée, et le deuxième paramètre correspond à diverses options, y compris les rappels de réussite et d'échec. L'URL de l'image sera transmise lors du rappel.
De cette façon, vous ne pouvez transmettre qu'une seule image, elle peut donc également être écrite sous la forme suivante :
var imagepool = initImagePool(10);
imagepool.load(["image1url","image2url"],{
Succès : fonction(src){
console.log("success:::::" src);
},
erreur : fonction(src){
console.log("erreur:::::" src);
>
});
En transmettant un tableau d'URL d'image, vous pouvez transmettre plusieurs images.
Chaque fois que l'image est chargée avec succès (ou échoue), la méthode de réussite (ou d'erreur) sera appelée et l'URL de l'image correspondante sera transmise.
Mais parfois, nous n'avons pas besoin de rappels aussi fréquents. Nous transmettons simplement un tableau d'URL d'images et rappelons une fois que toutes les images de ce tableau ont été traitées.
Ajoutez simplement une option :
var imagepool = initImagePool(10);
imagepool.load(["image1url ","image2url "],{
Succès : fonction (sArray, eArray, count){
console.log("sArray:::::" sArray);
console.log("eArray:::::" eArray);
console.log("count:::::" count);
},
erreur : fonction(src){
console.log("erreur:::::" src);
},
Une fois : vrai
});
En ajoutant un attribut once à l'option et en le définissant sur true, vous ne pouvez obtenir qu'un seul rappel.
Ce rappel rappellera inévitablement la méthode success. À ce stade, la méthode error est ignorée.
À ce stade, lors du rappel de la méthode de réussite, au lieu de transmettre un paramètre d'URL d'image, trois paramètres sont transmis, à savoir : le tableau d'URL réussies, le tableau d'URL ayant échoué et le nombre total d'images traitées.
De plus, il existe une méthode pour obtenir l'état interne du pool de connexions :
var imagepool = initImagePool(10);
console.log(imagepool.info());
En appelant la méthode info, vous pouvez obtenir l'état interne du pool de connexions à l'heure actuelle. La structure des données est la suivante :
Object.task.count Le nombre de tâches en attente de traitement dans le pool de connexions
Object.thread.count Nombre maximum de connexions dans le pool de connexions
Object.thread.free Nombre de connexions inactives dans le pool de connexions
Il est recommandé de ne pas appeler cette méthode fréquemment.
La dernière chose à noter est que si le chargement de l'image échoue, elle sera tentée jusqu'à 3 fois. Si le chargement échoue finalement, la méthode d'erreur sera rappelée. Le nombre de tentatives peut être modifié dans le code source.
Enfin, je voudrais souligner que les lecteurs peuvent pousser des images dans le pool de connexions autant qu'ils le souhaitent sans se soucier d'une concurrence excessive. Imagepool vous aidera à charger ces images de manière ordonnée.
Enfin et surtout, il faut noter qu'imagepool ne réduira théoriquement pas la vitesse de chargement des images, il s'agit simplement d'un chargement en douceur.
Code source
(fonction(exports){
//Cas unique
var instance = null;
var videFn = fonction(){};
//Configuration initiale par défaut
var config_default = {
//Le nombre de "threads" du pool de threads
Sujet : 5,
//Nombre de tentatives pour échec de chargement d'image
//Réessayez 2 fois, plus celle d'origine, soit un total de 3 fois
"essayer": 2
};
//Outils
var _helpers = {
//Définir les attributs dom
setAttr : (fonction(){
var img = new Image();
//Déterminer si le navigateur prend en charge l'ensemble de données HTML5
if(img.dataset){
fonction de retour (dom, nom, valeur){
dom.dataset[name] = valeur;
valeur de retour ;
};
}autre{
fonction de retour (dom, nom, valeur){
dom.setAttribute("data-" nom, valeur);
valeur de retour ;
};
}
}()),
//Obtenir les attributs dom
getAttr : (fonction(){
var img = new Image();
//Déterminer si le navigateur prend en charge l'ensemble de données HTML5
if(img.dataset){
fonction de retour (dom, nom){
Retourner dom.dataset[nom];
};
}autre{
fonction de retour (dom, nom){
return dom.getAttribute("data-" name);
};
}
}())
};
/**
*Méthode de construction
* @param max Le nombre maximum de connexions. valeur numérique.
*/
Fonction ImagePool(max){
//Nombre maximum de simultanéités
Ceci.max = max || config_default.thread;
This.linkHead = null;
This.linkNode = null;
//Chargement du pool
//[{img : dom,free : true, node : node}]
//nœud
//{src : "", options : {succès : "fn", erreur : "fn", une fois : vrai}, essayez : 0}
This.pool = [];
>
/**
* Initialisation
*/
ImagePool.prototype.initPool = fonction(){
var je,img,obj,_s;
_s = ceci ;
pour (i = 0;i < this.max; i ){
obj = {};
img = nouvelle image();
_helpers.setAttr(img, "id", i);
img.onload = fonction(){
var identifiant,src;
//回调
//_s.getNode(this).options.success.call(null, this.src);
_s.notice(_s.getNode(this), "succès", this.src);
//处理任务
_s.executeLink(this);
};
img.onerror = fonction(e){
var node = _s.getNode(this);
//判断尝试次数
if(node.try < config_default.try){
noeud.try = noeud.try 1;
//再次追加到任务链表末尾
_s.appendNode(_s.createNode(node.src, node.options, node.notice, node.group, node.try));
}autre{
//erreur回调
//node.options.error.call(null, this.src);
_s.notice(node, "erreur", this.src);
>
//处理任务
_s.executeLink(this);
};
obj.img = img;
obj.free = true;
this.pool.push(obj);
>
};
/**
* Encapsulation de rappel
* Nœud @param node. objet.
* Statut d'état @param. Chaîne. Valeurs facultatives : succès(succès)|erreur(échec)
* Chemin de l'image @param src. Chaîne.
*/
ImagePool.prototype.notice = function (nœud, statut, src){
node.notice(statut, src);
};
/**
* * Traitement des tâches de liste chaînée
* @param dom image dom objet. objet.
*/
ImagePool.prototype.executeLink = function(dom){
//判断链表是否存在节点
si(this.linkHead){
//加载下一个图片
this.setSrc(dom, this.linkHead);
//연결리스트 헤더 제거
This.shiftNode();
}그 외{
// 자신의 상태를 유휴 상태로 설정
This.status(dom, true);
}
};
/**
* 유휴 "스레드" 가져오기
*/
ImagePool.prototype.getFree = function(){
변수 길이,i;
for(i = 0, 길이 = this.pool.length; i
If(this.pool[i].free){
return this.pool[i];
}
}
null을 반환합니다.
};
/**
* src 속성 설정 캡슐화
* src 속성을 변경하는 것은 이미지를 로드하는 것과 동일하므로 작업이 캡슐화됩니다
* @param dom 이미지 dom 객체. 물체.
* @param 노드 노드. 물체.
*/
ImagePool.prototype.setSrc = 함수(dom, 노드){
//풀의 "스레드"를 유휴 상태가 아닌 상태로 설정
This.status(dom, false);
//연관 노드
This.setNode(dom, node);
//이미지 로드
dom.src = node.src;
};
/**
* 풀의 "스레드" 상태 업데이트
* @param dom 이미지 dom 객체. 물체.
* @param 상태 상태. 부울. 선택 값: true(유휴) | false(유휴 아님)
*/
ImagePool.prototype.status = 함수(dom, 상태){
var id = _helpers.getAttr(dom, "id");
This.pool[id].free = 상태;
//유휴 상태, 관련 노드 지우기
if(상태){
This.pool[id].node = null;
}
};
/**
* 풀에서 "스레드"의 관련 노드 업데이트
* @param dom 이미지 dom 객체. 물체.
* @param 노드 노드. 물체.
*/
ImagePool.prototype.setNode = 함수(dom, 노드){
var id = _helpers.getAttr(dom, "id");
This.pool[id].node = 노드;
return this.pool[id].node === node;
};
/**
* 풀에서 "스레드"의 관련 노드를 가져옵니다
* @param dom 이미지 dom 객체. 물체.
*/
ImagePool.prototype.getNode = 함수(dom){
var id = _helpers.getAttr(dom, "id");
return this.pool[id].node;
};
/**
* 외부 인터페이스, 사진 로딩
* @param src는 src 문자열이거나 src 문자열의 배열일 수 있습니다.
* @param 옵션 사용자 정의 매개변수. 포함: 성공 콜백, 오류 콜백, 일회 식별자.
*/
ImagePool.prototype.load = 함수(src, 옵션){
var srcs = [],
무료 = null,
길이 = 0,
i = 0,
//N'initialisez la stratégie de rappel qu'une seule fois
avis = (fonction(){
Si(options.une fois){
Fonction de retour (statut, src){
var g = this.group,
o = this.options;
//Enregistrement
g[statut].push(src);
//Déterminer si la réorganisation est terminée
Si(g.success.length g.error.length === g.count){
//En fait, il est exécuté séparément comme une autre tâche pour éviter que la fonction de rappel ne prenne trop de temps pour affecter la vitesse de chargement de l'image
setTimeout(function(){
o.success.call(null, g.success, g.error, g.count);
},1);
}
};
}autre{
Fonction de retour (statut, src){
var o = this.options;
//Rappel direct
setTimeout(function(){
o[status].call(null, src);
},1);
};
}
}()),
groupe = {
Compte : 0,
Succès : [],
erreur : []
},
node = null;
options = options || {};
options.succès = options.succès || videFn;
options.error = options.error ||
srcs = srcs.concat(src);
//그룹 요소 개수 설정
group.count = srcs.length;
//로드해야 하는 이미지를 탐색합니다
for(i = 0, 길이 = srcs.length; i
//노드 생성
노드 = this.createNode(srcs[i], 옵션, 공지, 그룹);
//스레드 풀이 사용 가능한지 확인
무료 = this.getFree();
if(무료){
//시간 있으면 바로 이미지 로딩
This.setSrc(free.img, node);
}그밖에{
//유휴 시간이 없습니다. 연결 목록에 작업을 추가하세요
This.appendNode(노드);
}
}
};
/**
* 내부 상태 정보 확인
* @returns {{}}
*/
ImagePool.prototype.info = function(){
var 정보 = {},
길이 = 0,
i = 0,
노드 = null;
//스레드
info.thread = {};
//총 스레드 수
info.thread.count = this.pool.length;
//유휴 스레드 수
info.thread.free = 0;
//작업
info.task = {};
//처리할 작업 개수
info.task.count = 0;
//유휴 "스레드" 수를 가져옵니다
for(i = 0, 길이 = this.pool.length; i
If(this.pool[i].free){
info.thread.free = info.thread.free 1;
}
}
//작업 수 가져오기(작업 체인 길이)
노드 = this.linkHead;
if(노드){
info.task.count = info.task.count 1;
동안(node.next){
info.task.count = info.task.count 1;
노드 = node.next;
}
}
반품 정보;
};
/**
* 노드 생성
* @param src 이미지 경로. 끈.
* @param 옵션 사용자 정의 매개변수. 포함: 성공 콜백, 오류 콜백, 일회 식별자.
* @param 공지 콜백 전략. 기능.
* @param 그룹 그룹 정보입니다. 물체. {횟수: 0, 성공: [], 오류: []}
* @param tr 오류 재시도 횟수입니다. 수치. 기본값은 0입니다.
* @returns {{}}
*/
ImagePool.prototype.createNode = function(src, options, notice, group, tr){
var node = {};
node.src = src;
node.options = options;
node.notice = notice;
node.group = group;
node.try = tr || 0;
return node;
};
/**
* 向任務鍊錶末端追加節點
* @param node 節點。對象。
*/
ImagePool.prototype.appendNode = function(node){
//判斷鍊錶是否為空
if(!this.linkHead){
this.linkHead = node;
this.linkNode = node;
}else{
this.linkNode.next = node;
this.linkNode = node;
}
};
/**
* 刪除鍊錶頭
*/
ImagePool.prototype.shiftNode = function(){
//判斷鍊錶是否存在節點
if(this.linkHead){
//修改鍊錶頭
this.linkHead = this.linkHead.next || null;
}
};
/**
* 匯出對外介面
* @param max 最大連線數。數值。
* @returns {{load: Function, info: Function}}
*/
exports.initImagePool = function(max){
if(!instance){
instance = new ImagePool(max);
instance.initPool();
}
return {
/**
* 載入圖片
*/
load: function(){
instance.load.apply(instance, arguments);
},
/**
* 內部資訊
* @returns {*|any|void}
*/
info: function(){
return instance.info.call(instance);
}
};
};
}(this));
以上就是這款特別棒的javascript前端圖片載入管理器的使用方法範例,小夥伴們學會使用了嗎?