تتيح لك الأحداث تشغيل كود عندما يحدث شيء ما في السلة. توجد تحت window.aftersell.cart.events.
الاشتراك هو استدعاء إعداد، لذا فهو آمن في أعلى سكربتك، دون حاجة لانتظار ready().
يسجّل events.on(event, handler) معالجًا ويُرجع دالة تلغي اشتراكه:
events.once(event, handler): يعمل مرة واحدة، ثم يلغي اشتراكه بنفسه.
events.off(event, handler): يزيل معالجًا محددًا.
المعالج الذي يرمي خطأً يُعزل ويُسجَّل في وحدة التحكم؛ وتستمر بقية المعالجات في العمل.
يعود كل خطأ متعلق بالأحداث تقريبًا إلى إحدى هاتين القاعدتين.
لا تغيّر السلة من cart_updated دون حارس
تغيير السلة داخل معالج cart_updated يطلق cart_updated مرة أخرى. وإذا غيّر ذلك المعالج السلة مجددًا، فلديك حلقة لا نهائية. سيشاهد المتسوق سلته تضطرب بينما تقصف الصفحة Shopify بالطلبات.
لا تستدعِ أبدًا إجراءً دون شرط من داخل cart_updated أو cart_loaded. احمِه بفحص للحالة التي أنت على وشك إنشائها، بحيث لا تفعل التمريرة الثانية شيئًا.
تمنحك السلة شبكة أمان واحدة: التحديث الذي ينتج سلة مطابقة لا يُصدر شيئًا، لذا فإن إعادة الجلب التي لا تغيّر شيئًا لن تعيد تشغيل الدورة. هذا يحميك من حلقات عديمة الأثر عرضية. لكنه لا يحميك من معالج يغيّر السلة فعليًا في كل مرة.
تعامل مع الحمولة على أنها للقراءة فقط
كل معالج لحدث واحد يستقبل الكائن نفسه. تعديله يغيّر ما تراه المعالجات التالية لمعالجك، بما فيها معالجات تخص تطبيقات أخرى على المتجر.
لتغيير السلة فعليًا، استخدم إجراءً. ولتغيير كيفية عرض البنود، استخدم registerLineTransform.
يُطلق مرة واحدة، عندما تُحمَّل السلة أول مرة على الصفحة. الحمولة هي كائن السلة الكامل.
استخدمه من أجل: أي شيء يحتاج إلى العمل على حالة السلة الابتدائية، مثل مطابقة هدية مجانية، أو تهيئة أداة، أو إبلاغ التحليلات بمحتويات السلة عند تحميل الصفحة.
يُعاد تشغيل cart_loaded للمشتركين المتأخرين. إذا اشتركت بعد تحميل السلة بالفعل، يُستدعى معالجك فورًا بالسلة الحالية. ترتيب الاشتراك لا يهم أبدًا، لذا لا داعي للقلق مما إذا كان سكربتك قد سبق السلة.
المنطق الذي يجب أن يكون صحيحًا عند تحميل الصفحة وعند كل تغيير لاحق ينبغي أن يشترك في كلٍ من cart_loaded وcart_updated بالدالة نفسها. هذا هو النمط القياسي لـ “إبقاء X متزامنًا مع السلة”.
يُطلق في كل مرة تتغير فيها محتويات السلة بعد التحميل الأول، سواء من الدرج أو من إجراءاتك أو من القالب أو من تطبيق آخر. الحمولة هي كائن السلة الكامل.
استخدمه من أجل: إبقاء شيء خارج السلة متزامنًا، مثل إجمالي مخصص أو شريط تقدم أو شارة ترويسة أو حدث تحليلات عند كل تغيير.
التحديث الذي ينتج سلة مطابقة لا يُصدر شيئًا. إعادة فتح الدرج، أو العودة إلى التبويب، أو إعادة الجلب التي تُرجع المحتويات نفسها لن تطلقه.
يُطلق عندما يظهر بند جديد في السلة. الحمولة هي { item }، حيث item هو بند السلة.
استخدمه من أجل: تتبّع الإضافة إلى السلة في أداة تحليلات تابعة لطرف ثالث. هذا هو الاستخدام الأكثر شيوعًا لـ SDK على الإطلاق. راجع تتبع الإضافة إلى السلة.
أمران يجب معرفتهما حول كيفية اشتقاقه:
تغيير الكمية ليس إضافة. تستنتج السلة الإضافات والإزالات بمقارنة البنود، لا الكميات. متسوق يرفع بندًا من 1 إلى 3 يطلق cart_updated وليس item_added. إذا احتجت إلى التقاط زيادات الكمية أيضًا، فقارن مع الحالة السابقة داخل معالج cart_updated.
كما أنه لا يُطلق للعناصر التي كانت في السلة بالفعل عند تحميل الصفحة؛ فتلك تصل عبر cart_loaded. إضافة عدة منتجات مختلفة دفعة واحدة تطلق الحدث مرة لكل بند.
يُطلق عندما يختفي بند من السلة. الحمولة هي { item }، وهي البند كما كان قبل اختفائه مباشرةً، لذا لا يزال بإمكانك قراءة key وvariantId وtitle الخاصة به.
استخدمه من أجل: عكس شيء فعلته عند الإضافة، مثل مسح علامة، أو إعادة إظهار عرض رفضه المتسوق، أو إبلاغ التحليلات بعمليات الإزالة.
نفس التحذير الخاص بـ item_added: خفض الكمية دون بلوغ الصفر ليس إزالة.
يُطلقان عند فتح الدرج وإغلاقه. بلا حمولة.
استخدمهما من أجل: تتبّع المشاهدات، أو إيقاف فيديو أو عرض شرائح خلف الدرج مؤقتًا، أو تبديل صنف (class) على الصفحة.
لا يُطلق أي منهما عند التحميل الأولي للصفحة، بل فقط عند فتح أو إغلاق فعلي.
يُطلق عندما ينقر المتسوق زر إتمام الشراء، مباشرةً قبل انتقال المتصفح. بلا حمولة.
استخدمه من أجل: تتبّع نية إتمام الشراء.
لا يمكنك إلغاء إتمام الشراء من هذا المعالج. الحدث إشعار وليس بوابة؛ يحدث الانتقال بغض النظر عما يفعله كودك. أبقِ المعالج سريعًا ومتزامنًا: قد لا يكتمل await أو استدعاء شبكة بطيء قبل تفريغ الصفحة. استخدم navigator.sendBeacon لأي شيء تحتاج إلى إرساله بشكل موثوق.
يُبثّ كل حدث أيضًا كـ CustomEvent من DOM على window، لذا يمكنك الاستماع دون لمس window.aftersell.cart. هذا مفيد من ملف قالب أو تطبيق تابع لطرف ثالث أو سكربت يُحمَّل مستقلًا عن السلة.
انتبه للتسمية: يستخدم الناقل snake_case، بينما تستخدم أحداث DOM صيغة kebab-case خلف البادئة aftersell:cart:.
تصل الحمولة على event.detail وتطابق كائن السلة. تُبثّ الأحداث على window، لذا يستقبلها مستمع في أي مكان على الصفحة. تُعرض السلة داخل shadow root، لكن حد الظل لا يقع أبدًا في مسار الحدث. كل بثّ يستنسخ الحمولة، لذا فإن مستمعًا يعدّل event.detail لا يمكن أن يؤثر على أي طرف آخر، ومستمعًا يرمي خطأً لا يمكن أن يعطّل SDK.
لا يُعاد تشغيل cart-loaded على DOM. يعيد الناقل تشغيل cart_loaded للمشتركين المتأخرين، لكن ذلك المسار يتجاوز بثّ DOM، لذا فإن window.addEventListener('aftersell:cart:cart-loaded') المسجَّل بعد تحميل السلة بالفعل لن يعمل أبدًا. إذا لم يكن ترتيب تحميل سكربتك مضمونًا، فاستخدم window.aftersell.cart.events.on('cart_loaded', …) الذي يُعاد تشغيله، أو استمع أيضًا إلى aftersell:cart:cart-updated.
أحداث سلة Shopify القياسية
بشكل منفصل، تنشر السلة أحداث السلة القياسية الخاصة بـ Shopify على document كلما غيّرت السلة، بحيث يستطيع كود القالب والتطبيقات الأخرى التفاعل مع تعديلات Aftersell بالطريقة نفسها التي تتفاعل بها مع تعديلات القالب:
الحمولة ليست على event.detail. يحمل detail فقط { source: 'aftersell' } — الوسم الذي تستخدمه السلة لتجاهل أحداثها الخاصة بدلًا من الدوران في حلقة. كل ما في الجدول أعلاه يُسند مباشرةً على كائن الحدث، لذا اقرأ event.action وليس event.detail.action.
يحمل كل حدث أيضًا promise يسوّيه Aftersell عند اكتمال عملية الكتابة الأساسية، بما يطابق معيار Shopify — انتظره بـ await ولا تحلّه بنفسك. تُبثّ هذه الأحداث على document وتتصاعد، لذا يستقبلها مستمع على window أيضًا.
- كائن السلة: الشكل الكامل للحمولات أعلاه.
- الإجراءات: كيفية تغيير السلة من داخل معالج.
- الخطافات: لتغيير كيفية عرض السلة، بدلًا من التفاعل معها.
- حالات الاستخدام: تتبّع التحليلات والهدايا المجانية وأمثلة كاملة أخرى.