Maison  >  Article  >  interface Web  >  La promesse Jquery implémente le chargement des images une par une_jquery

La promesse Jquery implémente le chargement des images une par une_jquery

WBOY
WBOYoriginal
2016-05-16 15:32:311509parcourir

Promise est l'une des spécifications de CommonJS. Elle comporte des méthodes de résolution, de rejet, de réalisation, d'échec, puis et d'autres, qui peuvent nous aider à contrôler le flux de code et à éviter l'imbrication multicouche des fonctions. De nos jours, l'asynchronie devient de plus en plus importante dans le développement Web. Pour les développeurs, ce type de programmation d'exécution non linéaire rendra difficile le contrôle des développeurs. Promise peut nous permettre de mieux contrôler le processus d'exécution du code. comme jQuery Toutes les bibliothèques ont déjà implémenté cet objet, et ES6, qui sortira à la fin de l'année, implémentera également nativement Promise.

Dans le mode proxy de la pratique des modèles de conception JavaScript - préchargement d'images, la fonction de préchargement d'images est implémentée en utilisant le mode proxy.

Allons maintenant plus loin et complétons une fonction qui permet de charger des images continues une par une.

Fonction :

1. Chargez les photos une par une.

2. Erreur de chargement, l'image d'échec de chargement s'affichera après l'expiration du délai.

Concernant les exigences fonctionnelles, il y aura certainement un traitement des événements d'état de chargement et des fonctions de rappel une fois terminés. Cela provoquera non seulement une confusion dans le code, mais détruira même divers principes, nous n'utiliserons donc plus de méthodes ordinaires pour l'écrire. . Compte tenu des caractéristiques de cette notification d'état, il est plus approprié d'utiliser l'architecture de promesse pour le traitement. La promesse est essentiellement une sorte de modèle de conception de publication par abonnement. Actuellement, cette fonction est développée en utilisant la promesse fournie avec jquery.

1. Complétez une fonction de création de proxy pour le chargement d'images, qui peut générer un proxy avec des capacités de surveillance du délai d'attente, des échecs, des succès et des annulations de chargement.

 function createLoadImgProxy(){
  var imgCache = new Image();
  var dfd = $.Deferred();
  var timeoutTimer;
  //开始加载超时监控,超时后进行reject操作
  function beginTimeoutWatcher(){
   timeoutTimer = setTimeout(function(){
   dfd.reject('timeout');
   }, 10000);
  }
  //结束加载超时监控
  function endTimeoutWatcher(){
   if(!timeoutTimer){
   return;
   }
   clearTimeout(timeoutTimer);
  }
  //加载完成事件处理,加载完成后进行resolve操作
  imgCache.onload = function(){
   dfd.resolve(this.src);
  };
  //加载终止事件处理,终止后进行reject操作
  imgCache.onabort = function(){
   dfd.reject("aborted");
  };
  //加载异常事件处理,异常后进行reject操作
  imgCache.onerror = function(){
   dfd.reject("error");
  };
  return function(eleImg, src){
   dfd.always(function(){
   //加载完成或加载失败都要终止加载超时监控
   endTimeoutWatcher();
   }).done(function(src){
   //加载完成后,往图片元素上设置图片
   loadImg(eleImg, src);
   }).fail(function(msg){
   //加载失败后,往图片元素上设置失败图片
   loadImg(eleImg, 'loadFailed.jpg');
   });
   loadImg(eleImg, 'loading.gif');
   imgCache.src = src;
   //开始进行超时加载监控
   beginTimeoutWatcher();
   return dfd.promise();
  };
  }

Parmi eux, un objet Différé est créé de la manière suivante

Copier le code Le code est le suivant :

var dfd = $.Deferred();

L'objet Deferred déclenche l'événement d'achèvement via la méthode de résolution et répond à l'événement d'achèvement en utilisant la méthode done.

Terminer l'événement lorsque le chargement est réussi.

Copier le code Le code est le suivant :

imgCache.onload = fonction(){
                  dfd.resolve(this.src);
                };

et le traitement de la réponse une fois le chargement terminé consistent à définir l'image sur l'élément. Le code suivant est un démontage de la méthode d'écriture en chaîne ci-dessus.

Copier le code Le code est le suivant :

dfd.done(fonction(src){
// Une fois le chargement terminé, définissez l'image sur l'élément image
LoadImg(eleImg, src);
                     });

L'objet Defferred déclenche un événement de rejet via la méthode de rejet et utilise la méthode fail pour répondre à l'événement de rejet, indiquant que le chargement a échoué.

Rejeter les événements lors du chargement du délai d'attente, de la résiliation ou de l'exception.                                                                    

 //开始加载超时监控,超时后进行reject操作
  function beginTimeoutWatcher(){
   timeoutTimer = setTimeout(function(){
   dfd.reject('timeout');
   }, 10000);
  }
  //加载终止事件处理,终止后进行reject操作
  imgCache.onabort = function(){
   dfd.reject("aborted");
  };
  //加载异常事件处理,异常后进行reject操作
  imgCache.onerror = function(){
   dfd.reject("error");
  };
Et le traitement des réponses en cas d'échec du chargement, la définition des images d'échec.                                                          


 dfd.fail(function(msg){
   //加载失败后,往图片元素上设置失败图片
   loadImg(eleImg, 'loadFailed.jpg');
   });
À la fin de la fonction proxy, renvoyez l'objet de promesse différée, qui est utilisé pour surveiller l'état d'achèvement et d'échec du chargement au lieu appelant afin de faciliter le chargement de l'image suivante.

retourner dfd.promise();


2. Chargement continu un par un

//一张一张的连续加载图片
  //参数:
  // srcs: 图片路径数组
  function doLoadImgs(srcs){
  var index = 0;
  (function loadOneByOne(){
   //退出条件
   if(!(s = srcs[index++])) {
   return;
   }
   var eleImg = createImgElement();
   document.getElementById('imgContainer').appendChild(eleImg);
   //创建一个加载代理函数
   var loadImgProxy = createLoadImgProxy();
   //在当前图片加载或失败后,递归调用,加载下一张
   loadImgProxy(eleImg, s).always(loadOneByOne);
  })();
  }
Créez une fonction de chargement récursif de loadOneByOne.

Un agent de chargement est d'abord créé en interne. Une fois que l'agent a chargé l'image, quel que soit le succès ou l'échec, la fonction loadOneByOne est appelée de manière récursive pour charger l'image suivante.

La clé réside dans l'objet promise renvoyé par la fonction proxy. Utilisez la méthode .always pour effectuer un appel récursif à loadOneByOne pour charger l'image suivante une fois le chargement terminé (succès ou échec).

loadImgProxy(eleImg, s).always(loadOneByOne);

至此完成。

采用了promise模式后,callback函数不见了,维护状态的函数和内部变量也不见了,代码更清晰简单,使得代理函数和本地函数之间的一致性得到保护。

完整代码:

<!DOCTYPE html>
<html>
 <head>
 <meta charset="utf-8">
 </head>
 <body>
 <button id='btnLoadImg'>加载图片</button>
 <br>
 <div id='imgContainer'>
 </div>
 <br>
 <script type='text/javascript' src="./jquery-1.11.3.min.js"></script>
 <script type='text/javascript'>
  var imgSrcs = [
  'http://img.wanchezhijia.com/A/2015/3/20/17/11/de63f77c-f74f-413a-951b-5390101a7d74.jpg',
  'http://www.newbridgemotorsport.com/files/6413/9945/0406/IMG_3630.jpg',
  'http://www.carsceneuk.com/wp-content/uploads/2015/03/88y9989.jpg',
  'http://mfiles.sohu.com/20130223/5ff_403b2e7a_7a1f_7f24_66eb_79e3f27d58cf_1.jpg',
  'http://img1.imgtn.bdimg.com/it/u=2678963350,1378052193&fm=21&gp=0.jpg'
  ];
  $(document).ready(function(){
  $('#btnLoadImg').bind('click', function(){
   doLoadImgs(imgSrcs);
  });
  });
  //创建img标签
  //这里用自执行函数加一个闭包,是为了可以创建多个id不同的img标签。
  var createImgElement = (function(){
  var index = 0;
  return function() {
   var eleImg = document.createElement('img');
   eleImg.setAttribute('width', '200');
   eleImg.setAttribute('heght', '150');
   eleImg.setAttribute('id', 'img' + index++);
   return eleImg;
  };
  })();
  function loadImg(img, src) {
  img.src = src;
  }
  function createLoadImgProxy(){
  var imgCache = new Image();
  var dfd = $.Deferred();
  var timeoutTimer;
  //开始加载超时监控,超时后进行reject操作
  function beginTimeoutWatcher(){
   timeoutTimer = setTimeout(function(){
   dfd.reject('timeout');
   }, 10000);
  }
  //结束加载超时监控
  function endTimeoutWatcher(){
   if(!timeoutTimer){
   return;
   }
   clearTimeout(timeoutTimer);
  }
  //加载完成事件处理,加载完成后进行resolve操作
  imgCache.onload = function(){
   dfd.resolve(this.src);
  };
  //加载终止事件处理,终止后进行reject操作
  imgCache.onabort = function(){
   dfd.reject("aborted");
  };
  //加载异常事件处理,异常后进行reject操作
  imgCache.onerror = function(){
   dfd.reject("error");
  };
  return function(eleImg, src){
   dfd.always(function(){
//   alert('always end');
   //加载完成或加载失败都要终止加载超时监控
   endTimeoutWatcher();
   }).done(function(src){
//   alert('done end');
   //加载完成后,往图片元素上设置图片
   loadImg(eleImg, src);
   }).fail(function(msg){
//   alert('fail end:' + msg);
   //加载失败后,往图片元素上设置失败图片
   loadImg(eleImg, 'loadFailed.jpg');
   });
   loadImg(eleImg, 'loading.gif');
   imgCache.src = src;
   //开始进行超时加载监控
   beginTimeoutWatcher();
   return dfd.promise();
  };
  }
  //一张一张的连续加载图片
  //参数:
  // srcs: 图片路径数组
  function doLoadImgs(srcs){
  var index = 0;
  (function loadOneByOne(){
   //退出条件
   if(!(s = srcs[index++])) {
   return;
   }
   var eleImg = createImgElement();
   document.getElementById('imgContainer').appendChild(eleImg);
   //创建一个加载代理函数
   var loadImgProxy = createLoadImgProxy();
   //在当前图片加载或失败后,递归调用,加载下一张
   loadImgProxy(eleImg, s).always(loadOneByOne);
  })();
  }
 </script>
 </body>
</html>
Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn