Shopify 在变体选择上触发功能,但不覆盖现有功能

cal*_*cle 1 javascript liquid shopify shopify-template

我在 Shopify 上使用“阁楼”主题。当我在产品页面上选择一个变体时,它们会将 SKU 和价格更新为该变体,我需要比这更多的功能,因为我想使用元字段显示每个变体的尺寸。

我创建了一个函数并在变体选择上调用它,如下所示:

jQuery(function($) {
  new Shopify.OptionSelectors('productSelect', {
    product: {{ product | json }},
    onVariantSelected: selectCallback,
    enableHistoryState: true
  });
});
Run Code Online (Sandbox Code Playgroud)

我的函数被调用,我可以执行我想要的操作。但这会阻止默认操作的发生,例如更新价格和 SKU。有没有办法可以同时调用两者?

bkn*_*hts 7

有多种方法可以完成这项工作。

首先,您需要了解您的主题本身是如何处理变体的。对于 loft,它使用 theme.Variant 对象,因此自定义变体选择非常简单:

jQuery('#shopify-section-product-template').on('theme:variants:changed', function(evt, variantObj){

   console.log('theme event for '+ variantObj.sku); // limited view of variant.
   console.log(variantObj);
});
Run Code Online (Sandbox Code Playgroud)

对于使用旧版 Shopify.OptionSelectors 的主题,您可以通过覆盖selectCallback全局函数来实现这个老派,例如:

(function(){
   var original_selectCallback = window.selectCallback;
   window.selectCallback = function(variant, selector) {
    original_selectCallback(variant, selector); // call the original function
    myCustomHandler(variant); // called with the full jsonified variant object.
};

})();
Run Code Online (Sandbox Code Playgroud)

最后,我处理过的大多数现代主题和使用 Shopify.OptionSelectors 的主题enableHistoryState: true允许您跳过覆盖的混乱并安装您自己的历史处理程序。这是您需要使用自己的脚本/液体组合获取变体和产品属性所需的 JSON 的地方:

document.addEventListener('DOMContentLoaded', function(){

function usePushState(handler){

    //modern themes use pushstate to track variant changes without reload
    function track (fn, handler, before) {
        return function interceptor () {
            if (before) {
                handler.apply(this, arguments);
                return fn.apply(this, arguments);
            } else {
                var result = fn.apply(this, arguments);
                handler.apply(this, arguments);
                return result;
            }
        };
    }

    var currentVariantId = null;
    function variantHandler () {
        var selectedVariantId = window.location.search.replace(/.*variant=(\d+).*/, '$1');
        console.log('checking variant change to '+ selectedVariantId);
        if(!selectedVariantId) return;
        if(selectedVariantId != currentVariantId){
            currentVariantId = selectedVariantId;
            handler(selectedVariantId);
        }
    }

    // Assign listeners
    window.history.pushState = track(history.pushState, variantHandler);
    window.history.replaceState = track(history.replaceState, variantHandler);
    window.addEventListener('popstate', variantHandler);
}


usePushState(function(variantId){
    console.log('variant: '+ variantId +' selected');
});
});
Run Code Online (Sandbox Code Playgroud)