مقدمة
ImagePool هي أداة JS لإدارة تحميل الصور. يمكن لـ ImagePool التحكم في عدد عمليات تحميل الصور المتزامنة.
لتحميل الصور ، الطريقة الأكثر بدائية هي كتابة علامة IMG مباشرة ، مثل: <img src = "url url" />.
بعد التحسين المستمر ، ظهر مخطط تحميل تأخير الصورة. هذه المرة ، لا يتم كتابة عنوان URL للصورة مباشرة في سمة SRC ، ولكن في سمة معينة ، مثل: <img src = "" data-src = "Image url" />. وبهذه الطريقة ، لن يقوم المتصفح بتحميل الصورة تلقائيًا. عند الحاجة إلى الوقت المناسب ، استخدم JS لوضع عنوان URL في سمة البيانات-SRC في سمة SRC لعلامة IMG ، أو بعد قراءة عنوان URL ، استخدم JS لتحميل الصورة ، وتعيين سمة SRC بعد التحميل ، وعرض الصورة.
يبدو أن هذا يتم التحكم فيه جيدًا ، ولكن لا يزال هناك مشاكل.
على الرغم من أنه لا يمكنه تحميل جزء من الصورة إلا ، إلا أن هذا الجزء من الصورة قد لا يزال ترتيبًا كبيرًا نسبيًا.
هذه ليست صفقة كبيرة بالنسبة لجانب الكمبيوتر ، ولكن بالنسبة لجانب الهاتف المحمول ، يتم تحميل الكثير من الصور المتزامنة ، والتي من المحتمل جدًا أن تتسبب في تعطل التطبيق.
لذلك ، نحتاج بشكل عاجل إلى آلية التخزين المؤقت للصور للتحكم في توافق تحميل الصورة. على غرار تجمع اتصال قاعدة بيانات الواجهة الخلفية ، لا ينشئ الكثير من الاتصالات ، ويمكنه إعادة استخدام كل اتصال بالكامل.
في هذه المرحلة ، ولد ImagePool.
مخطط تخطيطي سيء
تعليمات للاستخدام
أولاً ، قم بتهيئة تجمع الاتصال:
var imagePool = initimagePool (5) ؛
InitimagePool هي طريقة عالمية يمكن استخدامها مباشرة في أي مكان. تتمثل الوظيفة في إنشاء تجمع اتصال ، ويمكنك تحديد الحد الأقصى لعدد الاتصالات إلى تجمع الاتصال ، اختياريًا ، الافتراضي هو 5.
في نفس الصفحة ، تُرجع مكالمات متعددة إلى initimagePool نفس المثيل الأساسي ، والذي يعد دائمًا الأول ، مع وجود القليل من الشعور المفرد. على سبيل المثال:
نسخة الكود كما يلي:
var imagePool1 = initimagePool (3) ؛
var imagePool2 = initimagePool (7) ؛
في هذا الوقت ، يكون الحد الأقصى لعدد الاتصالات بين ImagePool1 و ImagePool2 هو 3 ، ويتم استخدام نفس المثيل الأساسي داخليًا. لاحظ أن النواة الداخلية هي نفسها ، وليس ذلك ImagePool1 === ImagePool2.
بعد التهيئة ، يمكنك تحميل الصورة بثقة.
أسهل طريقة للاتصال هي على النحو التالي:
نسخة الكود كما يلي:
var imagePool = initimagePool (10) ؛
imagepool.load ("Image url" ، {
النجاح: وظيفة (SRC) {
console.log ("النجاح :::::"+SRC) ؛
} ،
خطأ: الدالة (SRC) {
console.log ("error ::::"+SRC) ؛
}
}) ؛
فقط استدعاء طريقة التحميل على المثيل.
طريقة التحميل لها معلمتان. المعلمة الأولى هي عنوان URL للصور الذي يحتاج إلى تحميل ، والمعلمة الثانية هي خيارات مختلفة ، بما في ذلك عمليات الاسترداد الناجحة والفشل. سيتم تمرير عنوان URL الصورة أثناء عمليات الاسترجاعات.
وبهذه الطريقة ، يمكنك تمرير صورة واحدة فقط ، بحيث يمكن أيضًا كتابتها بالشكل التالي:
نسخة الكود كما يلي:
var imagePool = initimagePool (10) ؛
imagepool.load (["Image 1Url" ، "Image 2Url"] ، {
النجاح: وظيفة (SRC) {
console.log ("النجاح :::::"+SRC) ؛
} ،
خطأ: الدالة (SRC) {
console.log ("error ::::"+SRC) ؛
}
}) ؛
من خلال تمرير صفيف عنوان URL صورة ، يمكنك تمرير صور متعددة.
عند تحميل كل صورة بنجاح (أو فشل) ، سيتم استدعاء طريقة النجاح (أو الخطأ) وسيتم تمرير عنوان URL للصورة المقابل.
لكن في بعض الأحيان لا نحتاج إلى عمليات الاسترداد مثل هذا بشكل متكرر. تمرير في صفيف عنوان URL صورة. عندما تتم معالجة جميع الصور في هذه الصفيف ، تكون عمليات الاسترجاعات كافية.
فقط أضف خيار واحد:
نسخة الكود كما يلي:
var imagePool = initimagePool (10) ؛
imagepool.load (["Image 1Url" ، "Image 2Url"] ، {
النجاح: وظيفة (Sarray ، Earray ، Count) {
console.log ("Sarray ::::"+Sarray) ؛
console.log ("earray ::::"+earray) ؛
console.log ("count :::::"+count) ؛
} ،
خطأ: الدالة (SRC) {
console.log ("error ::::"+SRC) ؛
} ،
مرة واحدة: صحيح
}) ؛
عن طريق إضافة سمة مرة واحدة إلى الخيار ووضعه على TRUE ، يمكنك فقط تحقيق رد اتصال مرة واحدة.
هذه المرة ، يجب استدعاء طريقة النجاح مرة أخرى ، ويتم تجاهل طريقة الخطأ في هذا الوقت.
في هذا الوقت ، لم تعد طريقة نجاح رد الاتصال تمر بمعلمة عنوان URL للصور ، ولكن تمرير ثلاث معلمات ، وهي: صفيف URL الناجح ، صفيف URL الفاشل ، والعدد الإجمالي للصور المعالجة.
بالإضافة إلى ذلك ، هناك طريقة للحصول على الحالة الداخلية لمجموعة الاتصال:
نسخة الكود كما يلي:
var imagePool = initimagePool (10) ؛
console.log (imagePool.info ()) ؛
من خلال استدعاء طريقة المعلومات ، يمكنك الحصول على الحالة الداخلية لمجموعة الاتصال في الوقت الحالي ، وهيكل البيانات كما يلي:
object.task.count عدد المهام في انتظار المعالجة في مجموعة الاتصال
Object.Thread.count الحد الأقصى لعدد الاتصالات إلى تجمع الاتصال
Object.Thread.free عدد الاتصالات المجانية إلى تجمع الاتصال
يوصى بعدم استدعاء هذه الطريقة بشكل متكرر.
أخيرًا ، تجدر الإشارة إلى أنه إذا فشلت الصورة في التحميل ، فسيحاول ذلك على الأكثر 3 مرات. إذا فشلت الصورة في التحميل في النهاية ، فسيتم استدعاء طريقة الخطأ مرة أخرى. يمكن تعديل عدد المحاولات في رمز المصدر.
أخيرًا ، اسمحوا لي أن أؤكد أنه يمكن للقراء دفع الصور إلى تجمع الاتصال قدر الإمكان ، دون القلق بشأن التزامن المفرط. سوف تساعدك ImagePool على تحميل هذه الصور في حالة من الفوضى.
أخيرًا ، تجدر الإشارة إلى أن ImagePool لن يقلل نظريًا من سرعة تحميل الصورة ، فهو مجرد تحميل سلس.
رمز المصدر
نسخة الكود كما يلي:
(وظيفة (صادرات) {
//أعزب
var مثيل = null ؛
var reghfn = function () {} ؛
// التكوين الافتراضي الأولي
var config_default = {
// عدد "المواضيع" في تجمع الخيوط
الموضوع: 5 ،
// فشل عدد إعادة المحاولة في تحميل الصورة
// جرب مرتين ، أضف الأصلي ، ما مجموعه 3 مرات
"جرب": 2
} ؛
//أداة
var _helpers = {
// تعيين سمة DOM
setattr: (function () {
var img = new image () ؛
// احكم على ما إذا كان المتصفح يدعم مجموعة بيانات HTML5
if (img.dataset) {
وظيفة الإرجاع (دوم ، الاسم ، القيمة) {
dom.dataset [name] = value ؛
قيمة الإرجاع
} ؛
}آخر{
وظيفة الإرجاع (دوم ، الاسم ، القيمة) {
dom.setattribute ("Data-"+name ، value) ؛
قيمة الإرجاع
} ؛
}
} ()) ،
// الحصول على سمة DOM
getAttr: (function () {
var img = new image () ؛
// احكم على ما إذا كان المتصفح يدعم مجموعة بيانات HTML5
if (img.dataset) {
وظيفة الإرجاع (دوم ، الاسم) {
إرجاع dom.dataset [name] ؛
} ؛
}آخر{
وظيفة الإرجاع (دوم ، الاسم) {
إرجاع dom.getAttribute ("Data-"+name) ؛
} ؛
}
} ())
} ؛
/**
* طريقة بناء
* param أقصى عدد من الاتصالات. قيمة.
*/
وظيفة ImagePool (Max) {
// الحد الأقصى لعدد التزامن
this.max = max || config_default.thread ؛
this.linkhead = null ؛
this.linknode = null ؛
// حمام التجمع
// [{img: dom ، free: true ، node: node}]
//العقدة
// {src: "" ، الخيارات: {النجاح: "fn" ، خطأ: "fn" ، مرة واحدة: true} ، جرب: 0}
this.pool = [] ؛
}
/**
* التهيئة
*/
imagepool.prototype.initpool = function () {
var i ، img ، obj ، _s ؛
_s = هذا ؛
لـ (i = 0 ؛ i <this.max ؛ i ++) {
OBJ = {} ؛
IMG = صورة جديدة () ؛
_helpers.setattr (IMG ، "id" ، i) ؛
img.onload = function () {
var id ، src ؛
//أتصل مرة أخرى
//_s.getnode(this).options.success.call(null ، this.src) ؛
_s.notice (_s.getNode (هذا) ، "النجاح" ، this.src) ؛
// مهام المعالجة
_s.executelink (هذا) ؛
} ؛
img.onerror = function (e) {
var node = _s.getNode (this) ؛
// احكم على عدد المحاولات
if (node.try <config_default.try) {
Node.Try = Node.Try + 1 ؛
// أضف إلى نهاية قائمة المهام مرة أخرى
-
}آخر{
// خطأ رد الاتصال
//node.options.error.call(null ، this.src) ؛
_s.notice (العقدة ، "خطأ" ، this.src) ؛
}
// مهام المعالجة
_s.executelink (هذا) ؛
} ؛
OBJ.IMG = IMG ؛
obj.free = صحيح ؛
this.pool.push (obj) ؛
}
} ؛
/**
* تغليف رد الاتصال
* Param Node Node. هدف.
* حالة حالة param. خيط. القيمة الاختيارية: النجاح | خطأ (فشل)
* param src path path. خيط.
*/
imagepool.prototype.notice = دالة (العقدة ، الحالة ، src) {
Node.Notice (الحالة ، SRC) ؛
} ؛
/**
* معالجة مهام القائمة المرتبطة
* Param DOM Image DOM Object. هدف.
*/
imagepool.prototype.executelink = function (dom) {
// تمييز ما إذا كانت هناك عقد في القائمة المرتبطة
if (this.linkhead) {
// تحميل الصورة التالية
this.setsrc (dom ، this.linkhead) ؛
// قم بإزالة رأس الارتباط
this.shiftnode () ؛
}آخر{
// اضبط حالتك الخاصة على الخمول
this.status (dom ، true) ؛
}
} ؛
/**
* احصل على الخمول "موضوع"
*/
imagepool.prototype.getfree = function () {
var length ، i ؛
لـ (i = 0 ، طول = this.pool.length ؛ i <length ؛ i ++) {
if (this.pool [i] .free) {
إرجاع this.pool [i] ؛
}
}
العودة لاغية.
} ؛
/**
* تغليف إعدادات سمة SRC
* لأن تغيير سمة SRC يعادل تحميل الصورة ، قم بتغليف العملية
* Param DOM Image DOM Object. هدف.
* Param Node Node. هدف.
*/
imagepool.prototype.setsrc = function (dom ، node) {
// قم بتعيين "الخيط" في المسبح ليكون غير معدل
this.status (dom ، false) ؛
// العقدة التابعة
this.setNode (dom ، node) ؛
// تحميل الصورة
dom.src = node.src ؛
} ؛
/**
* تحديث حالة "الموضوع" في التجمع
* Param DOM Image DOM Object. هدف.
* حالة حالة param. منطقية. القيمة الاختيارية: صواب (خمول) | كاذب (غير متطابق)
*/
imagepool.prototype.status = function (dom ، status) {
var id = _helpers.getattr (dom ، "id") ؛
this.pool [id] .free = الحالة ؛
// حالة الخمول ، امسح العقدة المرتبطة بها
إذا (الحالة) {
this.pool [id] .node = null ؛
}
} ؛
/**
* تحديث العقدة المرتبطة بـ "الخيط" في التجمع
* Param DOM Image DOM Object. هدف.
* Param Node Node. هدف.
*/
ImagePool.Prototype.setNode = Function (DOM ، Node) {
var id = _helpers.getattr (dom ، "id") ؛
this.pool [id] .node = node ؛
إرجاع this.pool [id] .node === node ؛
} ؛
/**
* احصل على العقدة المرتبطة بـ "الخيط" في التجمع
* Param DOM Image DOM Object. هدف.
*/
imagepool.prototype.getNode = function (dom) {
var id = _helpers.getattr (dom ، "id") ؛
إرجاع this.pool [id] .node ؛
} ؛
/**
* واجهة خارجية ، تحميل الصور
* يمكن أن يكون Param SRC سلسلة SRC أو مجموعة من سلاسل SRC.
* param خيارات المعلمات المعرفة من قبل المستخدم. يتضمن: رد الاتصال الناجح ، رد الاتصال خطأ ، بمجرد العلامة.
*/
imagepool.prototype.load = function (SRC ، Options) {
var srcs = [] ،
مجاني = فارغ ،
الطول = 0 ،
أنا = 0 ،
// فقط تهيئة استراتيجية رد الاتصال مرة واحدة
إشعار = (دالة () {
if (Options.once) {
وظيفة الإرجاع (الحالة ، SRC) {
var g = this.group ،
o = this.options ؛
//سِجِلّ
G [الحالة] .push (SRC) ؛
// تمييز ما إذا كانت جميع عمليات إعادة التنظيم قد تمت معالجتها
if (g.success.length + g.error.length === G.Count) {
// غير متزامن
// في الواقع ، يتم تنفيذها بشكل منفصل كمهمة أخرى لمنع وظيفة رد الاتصال من التنفيذ لفترة طويلة والتأثير على سرعة تحميل الصورة
setTimeout (function () {
O.Success.Call (NULL ، G.SUCCESS ، G.ERROR ، G.COUNT) ؛
} ، 1) ؛
}
} ؛
}آخر{
وظيفة الإرجاع (الحالة ، SRC) {
var o = this.options ؛
// رد الاتصال المباشر
setTimeout (function () {
o [الحالة] .Call (NULL ، SRC) ؛
} ، 1) ؛
} ؛
}
} ()) ،
المجموعة = {
العد: 0 ،
نجاح: []،
خطأ: []
} ،
العقدة = null ؛
خيارات = خيارات || {} ؛
الخيارات. فارغة ؛
Options.error = Options.error || فارغة ؛
srcs = srcs.concat (src) ؛
// قم بتعيين عدد عناصر المجموعة
group.count = srcs.length ؛
// سافر فوق الصور التي يجب تحميلها
لـ (i = 0 ، طول = srcs.length ؛ i <length ؛ i ++) {
// إنشاء عقدة
node = this.createnode (srcs [i] ، الخيارات ، إشعار ، مجموعة) ؛
// احكم على ما إذا كان تجمع الخيوط مجانيًا
free = this.getFree () ؛
إذا (مجاني) {
// إذا كان لديك وقت فراغ ، فقم بتحميل الصورة على الفور
this.setsrc (free.img ، node) ؛
}آخر{
// لا خمول ، أضف المهمة إلى القائمة المرتبطة
this.appendnode (العقدة) ؛
}
}
} ؛
/**
* احصل على معلومات الحالة الداخلية
* returns {{}}
*/
imagepool.prototype.info = function () {
var info = {} ،
الطول = 0 ،
أنا = 0 ،
العقدة = null ؛
//خيط
info.Thread = {} ؛
// إجمالي عدد المواضيع
info.thread.count = this.pool.length ؛
// عدد المواضيع الخاملة
info.thread.free = 0 ؛
//مهمة
info.task = {} ؛
// عدد المهام المعلقة
info.task.count = 0 ؛
// احصل على عدد "المواضيع" المجانية
لـ (i = 0 ، طول = this.pool.length ؛ i <length ؛ i ++) {
if (this.pool [i] .free) {
info.thread.free = info.thread.free + 1 ؛
}
}
// احصل على عدد المهام (طول سلسلة المهام)
العقدة = this.linkhead ؛
إذا (العقدة) {
info.task.count = info.task.count + 1 ؛
بينما (node.next) {
info.task.count = info.task.count + 1 ؛
العقدة = node.next ؛
}
}
معلومات العودة ؛
} ؛
/**
* إنشاء عقدة
* param src path path. خيط.
* param خيارات المعلمات المعرفة من قبل المستخدم. يتضمن: رد الاتصال الناجح ، رد الاتصال خطأ ، بمجرد العلامة.
* param إشعار استراتيجية رد الاتصال. وظيفة.
* معلومات مجموعة Param Group. هدف. {العد: 0 ، النجاح: [] ، خطأ: []}
* param tr عدد أخطاء إعادة المحاولة. قيمة. الافتراضي هو 0.
* returns {{}}
*/
imagepool.prototype.createnode = function (SRC ، الخيارات ، الإشعار ، المجموعة ، tr) {
var node = {} ؛
node.src = src ؛
node.options = الخيارات ؛
node.notice = إشعار ؛
node.group = group ؛
Node.Try = tr || 0 ؛
عقدة العودة.
} ؛
/**
* إلحاق العقد إلى نهاية قائمة المهام
* Param Node Node. هدف.
*/
imagepool.prototype.appendnode = function (node) {
// احكم على ما إذا كانت القائمة المرتبطة فارغة
if (! this.linkhead) {
this.linkhead = العقدة ؛
this.linknode = node ؛
}آخر{
this.linknode.next = node ؛
this.linknode = node ؛
}
} ؛
/**
* حذف رأس الرابط
*/
imagepool.prototype.shiftnode = function () {
// تمييز ما إذا كانت هناك عقد في القائمة المرتبطة
if (this.linkhead) {
// تعديل رأس قائمة الارتباط
this.linkhead = this.linkhead.next || باطل؛
}
} ؛
/**
* تصدير الواجهة الخارجية
* param أقصى عدد من الاتصالات. قيمة.
* returns {{load: function ، info: function}}
*/
Exports.InitimagePool = function (max) {
إذا (! مثيل) {
مثيل = جديد ImagePool (كحد أقصى) ؛
مثيل. initpool () ؛
}
يعود {
/**
* تحميل الصور
*/
تحميل: function () {
مثيل. load.apply (مثيل ، وسيطات) ؛
} ،
/**
* المعلومات الداخلية
* returns {* | any | void}
*/
معلومات: وظيفة () {
return مثيل. info.call (مثيل) ؛
}
} ؛
} ؛
}(هذا))؛
ما سبق هو مثال على كيفية استخدام هذا مدير تحميل الصور الأمامي JavaScript الرائع بشكل خاص. هل تعلمت كيفية استخدامه؟