Prefácio
ImagePool é uma ferramenta JS para gerenciar o carregamento da imagem. O ImagePool pode controlar o número de cargas de imagem simultâneas.
Para carregamento de imagens, a maneira mais primitiva é escrever uma tag IMG diretamente, como: <img src = "imagem url" />.
Após a otimização contínua, apareceu um esquema de carregamento de atraso na imagem. Desta vez, o URL da imagem não é escrito diretamente no atributo SRC, mas em um determinado atributo, como: <img src = "" data-src = "imagem url" />. Dessa forma, o navegador não carregará automaticamente a imagem. Quando o tempo apropriado for necessário, use o JS para colocar o URL no atributo Data-SRC no atributo SRC da tag IMG ou depois de ler o URL, use JS para carregar a imagem e definir o atributo SRC após o carregamento e exiba a figura.
Isso parece ser bem controlado, mas ainda haverá problemas.
Embora só possa carregar uma parte da imagem, essa parte da imagem ainda pode ser uma ordem relativamente grande de magnitude.
Isso não é grande coisa para o lado do PC, mas para o lado móvel, muitas imagens simultâneas são carregadas, o que provavelmente causará falhas de aplicativos.
Portanto, precisamos urgentemente de um mecanismo de buffer de imagem para controlar a simultaneidade de carregamento da imagem. Semelhante ao pool de conexão do banco de dados de back -end, ele não cria muitas conexões e pode reutilizar completamente cada conexão.
Nesse ponto, o ImagePool nasceu.
Diagrama esquemático ruim
Instruções para uso
Primeiro, inicialize o pool de conexões:
var imagePool = initImagePool (5);
O InitimagePool é um método global que pode ser usado diretamente em qualquer lugar. A função é criar um pool de conexão e você pode especificar o número máximo de conexões com o pool de conexões, opcionalmente, o padrão é 5.
Na mesma página, várias chamadas para o InitimagePool retornam a mesma instância principal, que é sempre a primeira, com um sentimento de um pouco de singleton. por exemplo:
A cópia do código é a seguinte:
var imagePool1 = initImagePool (3);
var imagepool2 = initImagePool (7);
No momento, o número máximo de conexões entre ImagePool1 e ImagePool2 é 3 e a mesma instância principal é usada internamente. Observe que o núcleo interno é o mesmo, não o imagepool1 === imagepool2.
Após a inicialização, você pode carregar a imagem com confiança.
A maneira mais fácil de ligar é a seguinte:
A cópia do código é a seguinte:
var imagePool = initimagePool (10);
ImagePool.load ("Image URL", {
Sucesso: function (src) {
console.log ("Sucesso ::::"+src);
},
Erro: function (src) {
console.log ("Error :::"+src);
}
});
Basta chamar o método de carga na instância.
O método de carga possui dois parâmetros. O primeiro parâmetro é o URL da imagem que precisa ser carregado e o segundo parâmetro são várias opções, incluindo retornos de chamada bem -sucedidos e com falha. O URL da imagem será passado durante os retornos de chamada.
Dessa forma, você só pode passar em uma foto, para que ela também possa ser escrita na seguinte forma:
A cópia do código é a seguinte:
var imagePool = initimagePool (10);
ImagePool.load (["Image 1url", "Image 2url"], {
Sucesso: function (src) {
console.log ("Sucesso ::::"+src);
},
Erro: function (src) {
console.log ("Error :::"+src);
}
});
Ao passar em uma matriz de URL de imagem, você pode passar em várias imagens.
Quando cada imagem é carregada com sucesso (ou falhou), o método de sucesso (ou erro) será chamado e a URL da imagem correspondente será passada.
Mas às vezes não precisamos retornos de chamada como isso com frequência. Passe em uma matriz de URL de imagem. Quando todas as imagens nesta matriz são processadas, os retornos de chamada são suficientes.
Basta adicionar uma opção:
A cópia do código é a seguinte:
var imagePool = initimagePool (10);
ImagePool.load (["Image 1url", "Image 2url"], {
Sucesso: function (Sarray, exausta, contagem) {
console.log ("Sarray ::::"+Sarray);
console.log ("expor -se :::"+exenda);
console.log ("count :::::"+contagem);
},
Erro: function (src) {
console.log ("Error :::"+src);
},
uma vez: verdadeiro
});
Ao adicionar um atributo uma vez à opção e configurá -lo como true, você pode obter apenas um retorno de chamada uma vez.
Desta vez, o método de sucesso deve ser chamado de volta e o método de erro é ignorado no momento.
No momento, o método de sucesso de retorno de chamada não está mais passando em um parâmetro de URL de imagem, mas passando em três parâmetros, a saber: matriz de URL bem -sucedida, matriz de URL com falha e número total de imagens processadas.
Além disso, existe uma maneira de obter o estado interno do pool de conexões:
A cópia do código é a seguinte:
var imagePool = initimagePool (10);
console.log (imagepool.info ());
Ao chamar o método de informações, você pode obter o estado interno do pool de conexões no momento atual, e a estrutura de dados é a seguinte:
Object.Task.Count Número de tarefas aguardando processamento no pool de conexões
Object.Thread.Count O número máximo de conexões com o pool de conexões
Object.thread.free Número de conexões gratuitas para o pool de conexões
Recomenda -se não chamar esse método com frequência.
Finalmente, deve -se notar que, se a imagem não carregar, tentará no máximo três vezes. Se a imagem não carregar no final, o método de erro será chamado de volta. O número de tentativas pode ser modificado no código -fonte.
Por fim, deixe -me enfatizar que os leitores podem empurrar as imagens para o pool de conexões o máximo possível, sem se preocupar com a simultaneidade excessiva. O ImagePool ajudará você a carregar essas imagens em uma bagunça.
Por fim, deve -se notar que o ImagePool não reduzirá teoricamente a velocidade de carregamento da imagem, é apenas uma carga suave.
Código -fonte
A cópia do código é a seguinte:
(função (exportações) {
//Solteiro
Var instância = nulo;
var vaziofn = function () {};
// Configuração padrão inicial
var config_default = {
// O número de "threads" no pool de threads
Tópico: 5,
// O número de tentativa não conseguiu carregar a imagem
// tente duas vezes, adicione o original, um total de 3 vezes
"Tente": 2
};
//ferramenta
var _Helpers = {
// Defina o atributo dom
setattr: (function () {
var iMg = new Image ();
// julga se o navegador suporta o conjunto de dados HTML5
if (img.dataset) {
Função de retorno (dom, nome, valor) {
dom.dataset [nome] = value;
valor de retorno;
};
}outro{
Função de retorno (dom, nome, valor) {
dom.setAtAttribute ("dados-"+nome, valor);
valor de retorno;
};
}
} ()),
// obtenha atributo dom
getAtTr: (function () {
var iMg = new Image ();
// julga se o navegador suporta o conjunto de dados HTML5
if (img.dataset) {
Função de retorno (dom, nome) {
retornar dom.dataset [nome];
};
}outro{
Função de retorno (dom, nome) {
retornar dom.getAttribute ("dados-"+nome);
};
}
} ()))
};
/**
* Método de construção
* @param max número máximo de conexões. Valor.
*/
Função ImagePool (max) {
// Número máximo de simultaneidade
this.max = max || config_default.thread;
this.linkhead = null;
this.linkNode = null;
// Pool de carregamento
// [{img: dom, grátis: true, nó: nó}]
//nó
// {src: "", opções: {success: "fn", erro: "fn", uma vez: true}, tente: 0}
this.pool = [];
}
/**
* Inicialização
*/
Imagepool.prototype.initpool = function () {
var i, img, obj, _s;
_s = this;
for (i = 0; i <this.max; i ++) {
obj = {};
img = nova imagem ();
_Helpers.setAtTr (img, "id", i);
img.onload = function () {
var id, src;
//Ligar de volta
//_s.getNode(this).options.success.call(null, this.src);
_s.Notice (_S.GetNode (this), "Sucesso", this.src);
// Tarefas de processamento
_s.Executelink (isto);
};
img.onerror = function (e) {
var node = _s.getNode (this);
// julga o número de tentativas
if (node.try <config_default.try) {
node.Try = node.Try + 1;
// Adicione ao final da lista de tarefas novamente
_s.appendNode (_s.createnode (node.src, node.options, node.Notice, Node.Group, Node.try));
}outro{
// Retorno de chamada de erro
//node.options.error.call(null, this.src);
_s.Notice (Node, "Error", this.src);
}
// Tarefas de processamento
_s.Executelink (isto);
};
obj.img = img;
obj.Free = true;
this.pool.push (obj);
}
};
/**
* Encapsulamento de retorno de chamada
* Nó do nó @param. Objeto.
* status do @param status. Corda. Valor opcional: sucesso | Erro (falha)
* @Param SRC Path Image Path. Corda.
*/
ImagePool.prototype.Notice = function (nó, status, SRC) {
Node.Notice (Status, SRC);
};
/**
* Processando tarefas de lista vinculadas
* @param dom Objeto.
*/
Imagepool.prototype.executelink = function (dom) {
// discernir se existem nós na lista vinculada
if (this.linkhead) {
// Carregar a próxima foto
this.SetSrc (dom, this.linkhead);
// Remova o cabeçalho do link
this.ShiftNode ();
}outro{
// Defina seu próprio status para ocioso
this.status (dom, true);
}
};
/**
* Fique ocioso "thread"
*/
Imagepool.prototype.getFree = function () {
Var comprimento, i;
for (i = 0, comprimento = this.pool.length; i <comprimento; i ++) {
if (this.pool [i] .Free) {
devolver este.pool [i];
}
}
retornar nulo;
};
/**
* Encapsular as configurações de atributo SRC
* Como a alteração do atributo SRC é equivalente a carregar a imagem, encapsula a operação
* @param dom Objeto.
* Nó do nó @param. Objeto.
*/
Imagepool.prototype.setsrc = function (dom, node) {
// defina o "Thread" na piscina como não
this.status (dom, false);
// Nó afiliado
this.setNode (dom, nó);
// carrega a imagem
dom.src = node.src;
};
/**
* Atualize o status "Thread" no pool
* @param dom Objeto.
* status do @param status. Booleano. Valor opcional: true (inativo) | Falso (não-IDLE)
*/
Imagepool.prototype.status = function (dom, status) {
var id = _helpers.getAttr (dom, "id");
this.pool [id] .Free = status;
// Estado ocioso, limpe o nó associado
if (status) {
this.pool [id] .Node = null;
}
};
/**
* Atualize o nó associado de "Thread" na piscina
* @param dom Objeto.
* Nó do nó @param. Objeto.
*/
Imagepool.prototype.setNode = function (dom, nó) {
var id = _helpers.getAttr (dom, "id");
this.pool [id] .Node = node;
retornar this.pool [id] .Node === Node;
};
/**
* Obtenha o nó associado do "thread" na piscina
* @param dom Objeto.
*/
Imagepool.prototype.getNode = function (dom) {
var id = _helpers.getAttr (dom, "id");
Retorne this.pool [id] .Node;
};
/**
* Interface externa, carregar imagens
* @param src pode ser uma string src ou uma matriz de strings src.
* Opções @param Parâmetros definidos pelo usuário. Inclui: retorno de chamada de sucesso, retorno de chamada de erro, tag Once.
*/
Imagepool.prototype.load = function (src, opções) {
var srcs = [],
grátis = nulo,
comprimento = 0,
i = 0,
// Somente inicialize a estratégia de retorno de chamada uma vez
aviso = (function () {
if (options.once) {
Função de retorno (status, src) {
var g = this.Group,
o = this.options;
//Registro
g [status] .push (src);
// discernir se todas as reorganizações foram processadas
if (g.success.length + g.error.Length === G.Count) {
//assíncrono
// De fato, ele é executado separadamente como outra tarefa para impedir que a função de retorno de chamada execute muito tempo e afete a velocidade de carregamento da imagem
setTimeout (function () {
o.success.call (null, g.success, g.error, g.count);
}, 1);
}
};
}outro{
Função de retorno (status, src) {
var o = this.options;
// retorno de chamada direta
setTimeout (function () {
o [status] .call (null, src);
}, 1);
};
}
} ()),
grupo = {
contagem: 0,
Sucesso: [],
Erro: []
},
nó = nulo;
Opções = Opções || {};
options.success = options.success || vazio;
options.error = options.error || vazio;
srcs = srcs.concat (src);
// Defina o número de elementos de grupo
group.Count = srcs.length;
// viaja sobre as fotos que precisam ser carregadas
for (i = 0, comprimento = srcs.length; i <comprimento; i ++) {
// Crie um nó
node = this.createNode (srcs [i], opções, aviso, grupo);
// julga se o pool de threads é gratuito
grátis = this.getFree ();
se (grátis) {
// Se você tiver tempo livre, carregue a imagem imediatamente
this.SetSrc (free.img, nó);
}outro{
// sem ocioso, adicione a tarefa à lista vinculada
this.appendNode (nó);
}
}
};
/**
* Obtenha informações de status interno
* @returns {{}}
*/
Imagepool.prototype.info = function () {
var info = {},
comprimento = 0,
i = 0,
nó = nulo;
//Fio
info.thread = {};
// Número total de threads
info.thread.count = this.pool.length;
// Número de fios ociosos
info.thread.free = 0;
//Tarefa
info.task = {};
// Número de tarefas pendentes
info.task.count = 0;
// Obtenha o número de "threads" grátis
for (i = 0, comprimento = this.pool.length; i <comprimento; i ++) {
if (this.pool [i] .Free) {
info.thread.free = info.thread.free + 1;
}
}
// Obtenha o número de tarefas (comprimento da cadeia de tarefas)
nó = this.linkhead;
if (nó) {
info.task.count = info.task.count + 1;
while (node.next) {
info.task.count = info.task.count + 1;
node = node.next;
}
}
retornar informações;
};
/**
* Crie um nó
* @Param SRC Path Image Path. Corda.
* Opções @param Parâmetros definidos pelo usuário. Inclui: retorno de chamada de sucesso, retorno de chamada de erro, tag Once.
* @param avise Strategy de retorno de chamada. função.
* Informações do Grupo de Grupo @param. Objeto. {count: 0, sucesso: [], erro: []}
* @Param TR Número de erros de tentativa. Valor. O padrão é 0.
* @returns {{}}
*/
Imagepool.prototype.createnode = function (src, opções, aviso, grupo, tr) {
var node = {};
node.src = src;
node.options = opções;
Node.Notice = Aviso;
node.group = grupo;
node.Try = tr || 0;
Nó de retorno;
};
/**
* Anexar nós ao final da lista de tarefas
* Nó do nó @param. Objeto.
*/
Imagepool.prototype.appendNode = function (nó) {
// julga se a lista vinculada está vazia
if (! this.linkhead) {
this.linkhead = node;
this.linkNode = node;
}outro{
this.linknode.Next = node;
this.linkNode = node;
}
};
/**
* Exclua o cabeçalho do link
*/
Imagepool.prototype.shiftNode = function () {
// discernir se existem nós na lista vinculada
if (this.linkhead) {
// Modifique o cabeçalho da lista de links
this.linkhead = this.linkhead.next || nulo;
}
};
/**
* Exportar interface externa
* @param max número máximo de conexões. Valor.
* @returns {{load: function, info: function}}
*/
exports.initImagePool = function (max) {
if (! Instância) {
instância = new ImagePool (max);
instance.initpool ();
}
retornar {
/**
* Carregando fotos
*/
Load: function () {
instance.load.Apply (instância, argumentos);
},
/**
* Informações internas
* @returns {* | qualquer | void}
*/
info: function () {
return instance.info.call (instância);
}
};
};
}(esse));
O exposto acima é um exemplo de como usar esse gerenciador de carregamento de imagem de imagem front-end de JavaScript particularmente impressionante. Você aprendeu a usá -lo?