Préface
ImagePool est un outil JS pour gérer le chargement de l'image. ImagePool peut contrôler le nombre de charges d'images simultanées.
Pour le chargement d'image, le moyen le plus primitif est d'écrire directement une balise IMG, telle que: <img src = "Image URL" />.
Après optimisation continue, un schéma de chargement de retard d'image est apparu. Cette fois, l'URL de l'image n'est pas écrite directement dans l'attribut SRC, mais dans un certain attribut, tel que: <img src = "" data-src = "Image url" />. De cette façon, le navigateur ne chargera pas automatiquement l'image. Lorsque le temps approprié est nécessaire, utilisez JS pour mettre l'URL dans 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 et définissez l'attribut SRC après le chargement et affichez l'image.
Cela semble bien contrôlé, mais il y aura toujours des problèmes.
Bien qu'il ne puisse charger qu'une partie de l'image, cette partie de l'image peut toujours être un ordre de grandeur relativement important.
Ce n'est pas un problème pour le côté PC, mais pour le côté mobile, trop d'images simultanées sont chargées, ce qui est très susceptible de provoquer des accidents d'application.
Par conséquent, nous avons besoin de toute urgence d'un mécanisme de mémoire tampon d'image pour contrôler la charge de chargement de l'image. Semblable au pool de connexions de la base de données backend, il ne crée pas trop de connexions et peut réutiliser entièrement chaque connexion.
À ce stade, ImagePool est né.
Mauvais diagramme schématique
Instructions pour une utilisation
Tout d'abord, initialisez le pool de connexion:
var imagepool = initImagePool (5);
InimagePool est une méthode globale qui peut être utilisée directement n'importe où. La fonction consiste à créer un pool de connexion, et vous pouvez spécifier le nombre maximal de connexions au pool de connexions, éventuellement, la valeur par défaut est 5.
Dans la même page, plusieurs appels pour initimagepool renvoient la même instance de base, ce qui est toujours le premier, avec un peu de sensation de singleton. Par exemple:
La copie de code est la suivante:
var ImagePool1 = inInimagePool (3);
var ImagePool2 = inInimagePool (7);
À l'heure actuelle, le nombre maximum de connexions entre ImagePool1 et ImagePool2 est de 3, et la même instance de base est utilisée en interne. Notez que le noyau interne est le même, pas que ImagePool1 === ImagePool2.
Après initialisation, vous pouvez charger l'image avec confiance.
La façon la plus simple d'appeler est la suivante:
La copie de code est la suivante:
var imagePool = inInimagePool (10);
ImagePool.load ("URL d'image", {
Succès: fonction (src) {
console.log ("Success :::::" + Src);
},
Erreur: fonction (src) {
console.log ("Erreur ::::" + Src);
}
});
Appelez simplement la méthode de chargement sur l'instance.
La méthode de charge a deux paramètres. Le premier paramètre est l'URL d'image qui doit être chargé, et le deuxième paramètre est diverses options, y compris des rappels réussis et ratés. L'URL de l'image sera transmise pendant les rappels.
De cette façon, vous ne pouvez passer que sur une seule image, donc il peut également être écrit sous la forme suivante:
La copie de code est la suivante:
var imagePool = inInimagePool (10);
ImagePool.load (["Image 1Url", "Image 2Url"], {
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.
Lorsque chaque image est chargée avec succès (ou échoué), la méthode de succès (ou d'erreur) sera appelée et l'URL d'image correspondante sera transmise.
Mais parfois, nous n'avons pas besoin de rappels comme celui-ci fréquemment. Passez dans un tableau d'URL d'image. Lorsque toutes les images de ce tableau sont traitées, les rappels sont suffisants.
Ajoutez simplement une option:
La copie de code est la suivante:
var imagePool = inInimagePool (10);
ImagePool.load (["Image 1Url", "Image 2Url"], {
Succès: fonction (sarray, oreille, comte) {
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 une fois à l'option et en le définissant sur true, vous ne pouvez réaliser un rappel qu'une seule fois.
Cette fois, la méthode de réussite doit être rappelée et la méthode d'erreur est ignorée pour le moment.
À l'heure actuelle, la méthode de réussite de rappel ne transmet plus dans un paramètre d'URL d'image, mais passant en trois paramètres, à savoir: tableau URL réussi, tableau URL défaillant et nombre total d'images traitées.
De plus, il existe un moyen d'obtenir l'état interne du pool de connexion:
La copie de code est la suivante:
var imagePool = inInimagePool (10);
console.log (imagepool.info ());
En appelant la méthode d'informations, vous pouvez obtenir l'état interne du pool de connexions à l'heure actuelle, et la structure des données est la suivante:
Object.task.Count Nombre de tâches en attente de traitement dans le pool de connexion
Object.thread.Count le nombre maximum de connexions au pool de connexions
Object.thread. nombre de connexions libres au pool de connexions
Il est recommandé de ne pas appeler fréquemment cette méthode.
Enfin, il convient de noter que si l'image ne se charge pas, il essaiera au plus 3 fois. Si l'image ne se charge pas à la fin, la méthode d'erreur sera rappelée. Le nombre de tentatives peut être modifié dans le code source.
Enfin, permettez-moi de souligner que les lecteurs peuvent pousser les images dans le pool de connexions autant que possible, sans se soucier d'une concurrence excessive. ImagePool vous aidera à charger ces images en désordre.
Enfin, il faut noter que ImagePool ne réduira pas théoriquement la vitesse de chargement de l'image, c'est juste un chargement lisse.
Code source
La copie de code est la suivante:
(fonction (exportations) {
//Célibataire
var instance = null;
var videfn = function () {};
// Configuration par défaut initiale
var config_default = {
// le nombre de "threads" dans le pool de threads
Sujet: 5,
// Le nombre de réessais n'a pas chargé l'image
// Essayez deux fois, ajoutez l'original, un total de 3 fois
"Essayez": 2
};
//outil
var _helpers = {
// Définir l'attribut DOM
setAttr: (function () {
var img = new image ();
// juger si le navigateur prend en charge l'ensemble de données HTML5
if (img.dataset) {
return function (dom, nom, valeur) {
dom.dataset [name] = valeur;
valeur de retour;
};
}autre{
return function (dom, nom, valeur) {
dom.setAttribute ("data -" + name, valeur);
valeur de retour;
};
}
} ()),
// Obtenez l'attribut DOM
getAttr: (function () {
var img = new image ();
// juger si le navigateur prend en charge l'ensemble de données HTML5
if (img.dataset) {
return function (dom, name) {
return dom.dataset [name];
};
}autre{
return function (dom, name) {
return dom.getAttribute ("data -" + name);
};
}
} ())
};
/ **
* Méthode de construction
* @param maximum maximum de connexions. Valeur.
* /
fonction imagepool (max) {
// Nombre maximum de concurrence
this.max = max || config_default.thread;
this.Linkhead = null;
this.linkNode = null;
// Pool de chargement
// [{img: dom, libre: true, node: node}]
//nœud
// {src: "", options: {Success: "fn", erreur: "fn", une fois: true}, essayez: 0}
this.pool = [];
}
/ **
* Initialisation
* /
Imagepool.prototype.initpool = fonction () {
var i, img, obj, _s;
_s = this;
for (i = 0; i <this.max; i ++) {
obj = {};
img = new image ();
_helpers.setattr (img, "id", i);
img.onload = function () {
var id, src;
// rappel
//_s.getNode(this).options.success.call(null, this.src);
_s.Notice (_s.getNode (this), "Success", this.src);
// Traitement des tâches
_s.ExECUTELINK (this);
};
img.onerror = fonction (e) {
var node = _s.getNode (this);
// juge le nombre de tentatives
if (node.try <config_default.try) {
node.try = node.try + 1;
// Ajouter à nouveau à la fin de la liste des tâches
_S.APPEndNode (_s.Creenode (node.src, node.options, node.notice, node.group, node.try));
}autre{
// rappel d'erreur
//node.options.error.call(null, this.src);
_s.Notice (noeud, "error", this.src);
}
// Traitement des tâches
_s.ExECUTELINK (this);
};
obj.img = img;
obj.free = true;
this.pool.push (obj);
}
};
/ **
* Encapsulation de rappel
* Node de nœud @param. Objet.
* Statut de statut @param. Chaîne. Valeur facultative: succès | Erreur (échec)
* @Param SRC Image Path. Chaîne.
* /
Imagepool.prototype.notice = fonction (nœud, status, src) {
node.notice (statut, src);
};
/ **
* Traitement des tâches de liste liée
* @param Dom Image Dom Object. Objet.
* /
Imagepool.prototype.execUtreLink = fonction (dom) {
// discerner s'il y a des nœuds dans la liste liée
if (this.linkhead) {
// Chargez l'image suivante
this.setsrc (dom, this.linkhead);
// Retirez l'en-tête de liaison
this.shiftNode ();
}autre{
// Définissez votre propre statut sur le ralenti
this.status (dom, true);
}
};
/ **
* Obtenez un "fil" inactif
* /
Imagepool.prototype.getFree = function () {
longueur var, i;
pour (i = 0, longueur = this.pool.length; i <longueur; i ++) {
if (this.pool [i] .free) {
Renvoyez ce.pool [i];
}
}
retourner null;
};
/ **
* Encapsuler les paramètres d'attribut SRC
* Parce que la modification de l'attribut SRC est équivalente au chargement de l'image, encapsulez l'opération
* @param Dom Image Dom Object. Objet.
* Node de nœud @param. Objet.
* /
Imagepool.prototype.setsrc = fonction (dom, node) {
// Définissez le "thread" dans la piscine pour ne pas être en cours
this.status (dom, false);
// nœud affilié
this.setNode (dom, nœud);
// Chargez l'image
dom.src = node.src;
};
/ **
* Mettez à jour l'état "Thread" dans la piscine
* @param Dom Image Dom Object. Objet.
* Statut de statut @param. Boolean. Valeur facultative: true (inactif) | Faux (non-Idle)
* /
Imagepool.prototype.status = fonction (Dom, Status) {
var id = _helpers.getattr (dom, "id");
this.pool [id] .free = statut;
// état d'inactivité, effacer le nœud associé
if (status) {
this.pool [id] .node = null;
}
};
/ **
* Mettez à jour le nœud associé de "thread" dans la piscine
* @param Dom Image Dom Object. Objet.
* Node de nœud @param. Objet.
* /
Imagepool.prototype.setnode = fonction (dom, node) {
var id = _helpers.getattr (dom, "id");
this.pool [id] .node = node;
return this.pool [id] .node === node;
};
/ **
* Obtenez le nœud associé du "thread" dans la piscine
* @param Dom Image Dom Object. Objet.
* /
Imagepool.prototype.getNode = fonction (dom) {
var id = _helpers.getattr (dom, "id");
return this.pool [id] .Node;
};
/ **
* Interface externe, chargement des images
* @param src peut être une chaîne SRC ou un tableau de chaînes SRC.
* @Param Options Paramètres définis par l'utilisateur. Comprend: Success Rappel, rappel d'erreur, une fois la balise.
* /
Imagepool.prototype.load = fonction (src, options) {
var srcs = [],
gratuit = null,
longueur = 0,
i = 0,
// Initialise la stratégie de rappel une seule fois
remarque = (fonction () {
if (options.once) {
return function (status, src) {
var g = this.group,
o = this.options;
//Enregistrer
g [statut] .push (src);
// discerner si toutes les réorganisations ont été traitées
if (g.success.length + g.error.length === g.Count) {
//asynchrone
// En fait, il est exécuté séparément comme une autre tâche pour empêcher la fonction de rappel d'exécuter trop longtemps et affectant la vitesse de chargement de l'image
setTimeout (function () {
O.Success.Call (null, G.Success, G.Error, G.Count);
}, 1);
}
};
}autre{
return function (status, src) {
var o = this.options;
// rappel direct
setTimeout (function () {
o [statut] .Call (null, src);
}, 1);
};
}
} ()),
groupe = {
Compter: 0,
succès: [],
erreur: []
},
Node = null;
Options = Options || {};
options.success = options.success || videfn;
options.error = options.error || videfn;
srcs = srcs.concat (src);
// Définit le nombre d'éléments de groupe
group.count = srcs.length;
// voyage sur les photos qui doivent être chargées
pour (i = 0, longueur = srcs.length; i <longueur; i ++) {
// Créer un nœud
Node = this.Creenode (srcs [i], options, notification, groupe);
// juge si le pool de threads est gratuit
free = this.getFree ();
if (gratuit) {
// Si vous avez du temps libre, chargez l'image immédiatement
this.setsrc (free.img, nœud);
}autre{
// pas d'inactivité, ajoutez la tâche à la liste liée
this.appendNode (nœud);
}
}
};
/ **
* Obtenir des informations sur l'état interne
* @returns {{}}
* /
Imagepool.prototype.info = function () {
var info = {},
longueur = 0,
i = 0,
Node = null;
//Fil
info.thread = {};
// Nombre total de threads
info.thread.count = this.pool.length;
// Nombre de threads inactifs
info.thread.free = 0;
//Tâche
info.task = {};
// Nombre de tâches en attente
info.task.count = 0;
// obtient le nombre de "threads" gratuits
pour (i = 0, longueur = this.pool.length; i <longueur; i ++) {
if (this.pool [i] .free) {
info.thread.free = info.thread.free + 1;
}
}
// obtient le nombre de tâches (longueur de chaîne de tâches)
Node = this.Linkhead;
if (node) {
info.task.count = info.task.count + 1;
while (node.next) {
info.task.count = info.task.count + 1;
node = node.next;
}
}
retour des informations;
};
/ **
* Créez un nœud
* @Param SRC Image Path. Chaîne.
* @Param Options Paramètres définis par l'utilisateur. Comprend: Success Rappel, rappel d'erreur, une fois la balise.
* @param Stratégie de rappel de préavis. fonction.
* Informations de groupe de groupe @param. Objet. {count: 0, succès: [], erreur: []}
* @param tr Number of Reprying Errers. Valeur. La valeur par défaut est 0.
* @returns {{}}
* /
Imagepool.prototype.creenode = fonction (src, options, notification, groupe, tr) {
var node = {};
node.src = src;
Node.options = Options;
node.notice = note;
Node.group = groupe;
node.try = tr || 0;
Node de retour;
};
/ **
* Ajouter les nœuds à la fin de la liste des tâches
* Node de nœud @param. Objet.
* /
Imagepool.prototype.appendNode = fonction (node) {
// juger si la liste liée est vide
if (! this.linkhead) {
this.Linkhead = node;
this.linkNode = node;
}autre{
this.linkNode.next = node;
this.linkNode = node;
}
};
/ **
* Supprimer l'en-tête du lien
* /
Imagepool.prototype.shiftNode = function () {
// discerner s'il y a des nœuds dans la liste liée
if (this.linkhead) {
// Modifiez l'en-tête de la liste des liens
this.linkhead = this.linkhead.next || nul;
}
};
/ **
* Exporter l'interface externe
* @param maximum maximum de connexions. Valeur.
* @returns {{chargement: fonction, info: fonction}}
* /
exportS.InitimagePool = fonction (max) {
if (! instance) {
instance = new ImagePool (max);
instance.initpool ();
}
retour {
/ **
* Chargement des images
* /
chargement: fonction () {
instance.load.apply (instance, arguments);
},
/ **
* Informations internes
* @returns {* | tout | vide}
* /
info: function () {
return instance.info.call (instance);
}
};
};
}(ce));
Ce qui précède est un exemple de la façon d'utiliser ce gestionnaire de chargement d'image frontal JavaScript particulièrement impressionnant. Avez-vous appris à l'utiliser?