为什么我必须触发两次点击事件才能触发正确的数据层?

Why do I have to trigger a click event twice to get the proper dataLayer to fire?

上下文

我正在尝试将事件推送到 Shopify 网站上的数据层。我正在使用一个结合了 liquid 和 JS 代码的 liquid 文件从站点中提取适当的数据以推送到数据层。除了“从购物车中删除”事件外,所有事件都正常触发。

问题描述

最初的问题是“从购物车中删除”事件数据层推送从未触发,因为购物车页面在推送之前重新加载以显示更新后的购物车。

使用下面的代码,我现在可以触发“从购物车中删除”事件,但它只会在第二次单击删除图标时触发。

问题

如何在重新加载购物车之前首次单击删除图标时触发“从购物车中删除”事件推送?

JS/Liquid 辅助文件

为简洁起见删除了不必要的代码。

if(!window.jQuery){
    var jqueryScript = document.createElement('script');
    jqueryScript.setAttribute('src','https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js');
    document.head.appendChild(jqueryScript);
}

__DL__jQueryinterval = setInterval(function(){
    // wait for jQuery to load & run script after jQuery has loaded
    if(window.jQuery){
        
        /**********************
        * DYNAMIC DEPENDENCIES
        ***********************/

        __DL__ = {
            dynamicCart: true,  // if cart is dynamic (meaning no refresh on cart add) set to true
            debug: true, // if true, console messages will be displayed
            cart:  true,
            removeCart: true
        };

        customBindings = {
            cartTriggers: [],
            viewCart: [],
            removeCartTrigger: [],
        };

        /* DO NOT EDIT */
        defaultBindings = {
            //removeCartTrigger: ['[href*="/cart/change"]'],
            removeCartTrigger: ['.tests'],
        };

        // stitch bindings
        objectArray = customBindings;
        outputObject = __DL__;

        applyBindings = function(objectArray, outputObject){
            for (var x in objectArray) {
                var key = x;
                var objs = objectArray[x];
                values = [];
                if(objs.length > 0){
                    values.push(objs);
                    if(key in outputObject){
                        values.push(outputObject[key]);
                        outputObject[key] = values.join(", ");
                    }else{
                        outputObject[key] = values.join(", ");
                    }
                }
            }
        };

        applyBindings(customBindings, __DL__);
        applyBindings(defaultBindings, __DL__);

        /**********************
        * DATALAYER SECTIONS
        ***********************/

                /** DATALAYER: Cart View
                * Fire anytime a user views their cart (non-dynamic) */
                {% if template contains 'cart' %}
                var cart = {
                    'products':[{% for line_item in cart.items %}{
                        'id'       : {{line_item.product_id | json}},
                        'sku'      : {{line_item.sku | json}},
                        'variant'  : {{line_item.variant_id | json}},
                        'name'     : {{line_item.title | json}},
                        'price'    : {{line_item.price | money_without_currency | remove: "," | json}},
                        'quantity' : {{line_item.quantity | json}}
                    },{% endfor %}],
                    'pageType' : 'Cart',
                    'event'    : 'Cart'
                };

                dataLayer.push(cart);

                if(__DL__.debug){
                    console.log("Cart"+" :"+JSON.stringify(cart, null, " "));
                }

                __DL__.cart = cart.products;

                $(__DL__.removeCartTrigger).on('click', function (event) {
                    setTimeout(function(){
                       //const goTo = $(this).attr("data-href");  // store anchor href
                        // remove from cart
                        jQuery.getJSON("/cart", function (response) {
                            // get Json response
                            __DL__.removeCart = response;
                            var removeFromCart = {
                                'products': __DL__.removeCart.items.map(function (line_item) {
                                    return {
                                        'id'       : line_item.product_id,
                                        'sku'      : line_item.sku,
                                        'variant'  : line_item.variant_id,
                                        'name'     : line_item.title,
                                        'price'    : (line_item.price/100),
                                        'quantity' : line_item.quantity
                                    }
                                }),
                                'pageType' : 'Remove from Cart',
                                'event'    : 'Remove from Cart'
                            };
                            __DL__.removeCart = removeFromCart;

                            var cartIDs = [];
                            var removeIDs = [];
                            var removeCart = [];

                            // remove from cart logic
                            for(var i=__DL__.cart.length-1;i>=0;i--){var x=parseFloat(__DL__.cart[i].variant);cartIDs.push(x)}for(var i=__DL__.removeCart.products.length-1;i>=0;i--){var x=parseFloat(__DL__.removeCart.products[i].variant);removeIDs.push(x)}function arr_diff(b,c){var a=[],diff=[];for(var i=0;i<b.length;i++){a[b[i]]=true}for(var i=0;i<c.length;i++){if(a[c[i]]){delete a[c[i]]}else{a[c[i]]=true}}for(var k in a){diff.push(k)}return diff};var x=arr_diff(cartIDs,removeIDs)[0];for(var i=__DL__.cart.length-1;i>=0;i--){if(__DL__.cart[i].variant==x){removeCart.push(__DL__.cart[i])}}

                            dataLayer.push(removeCart);

                            if (__DL__.debug) {
                                console.log("Item Removed from Cart"+" :"+JSON.stringify(removeCart, null, " "));
                            }
                        });
                    }, 2000);
                });

                {% endif %}

                            /**********************
                            * DATALAYER EVENT BINDINGS
                            ***********************/

                            /** DATALAYER:
                            * Add to Cart / Dynamic Cart View
                            * Fire all pages trigger after all additional dataLayers have loaded. */

                            $(document).ready(function() {

                                /** DATALAYER: Cart */

                                // stage cart data
                                function mapJSONcartData(){
                                    jQuery.getJSON('/cart.js', function (response) {
                                        // get Json response
                                        __DL__.cart = response;
                                        var cart = {
                                            'products': __DL__.cart.items.map(function (line_item) {
                                                return {
                                                    'id'       : line_item.id,
                                                    'sku'      : line_item.sku,
                                                    'variant'  : line_item.variant_id,
                                                    'name'     : line_item.title,
                                                    'price'    : (line_item.price/100),
                                                    'quantity' : line_item.quantity
                                                }
                                            }),
                                            'pageType' : 'Cart',
                                            'event'    : 'Cart'
                                        };
                                        if(cart.products.length > 0){
                                            dataLayer.push(cart);
                                            if (__DL__.debug) {
                                                console.log("Cart"+" :"+JSON.stringify(cart, null, " "));
                                            }
                                        }
                                    });
                                }

                                viewcartfire = 0;

                                // view cart
                                $(__DL__.viewCart).on('click', function (event) {
                                    if(viewcartfire !== 1){
                                        viewcartfire = 1;
                                        // if dynamic cart is TRUE
                                        if (__DL__.dynamicCart) {
                                            cartCheck = setInterval(function () {
                                                // begin check interval
                                                if ($(__DL__.cartVisableSelector).length > 0) {
                                                    // check visible selectors
                                                    clearInterval(cartCheck);
                                                    mapJSONcartData();
                                                    $(__DL__.removeCartTrigger).on('click', function (event) {
                                                        // remove from cart
                                                        var link = $(this).attr("href");
                                                        jQuery.getJSON(link, function (response) {
                                                            // get Json response
                                                            __DL__.removeCart = response;
                                                            var removeFromCart = {
                                                                'products': __DL__.removeCart.items.map(function (line_item) {
                                                                    return {
                                                                        'id'       : line_item.id,
                                                                        'sku'      : line_item.sku,
                                                                        'variant'  : line_item.variant_id,
                                                                        'name'     : line_item.title,
                                                                        'price'    : (line_item.price/100),
                                                                        'quantity' : line_item.quantity
                                                                    }
                                                                }),
                                                                'pageType' : 'Remove from Cart',
                                                                'event'    : 'Remove from Cart'
                                                            };
                                                            dataLayer.push(removeFromCart);
                                                            if (__DL__.debug) {
                                                                console.log("Cart"+" :"+JSON.stringify(removeFromCart, null, " "));
                                                            }
                                                        });
                                                    });
                                                }
                                            }, 500);
                                        }
                                    }
                                });

                                // add to cart
                                jQuery.getJSON('/cart.js', function (response) {
                                    // get Json response
                                    __DL__.cart = response;
                                    var cart = {
                                        'products': __DL__.cart.items.map(function (line_item) {
                                            return {
                                                'id'       : line_item.id,
                                                'sku'      : line_item.sku,
                                                'variant'  : line_item.variant_id,
                                                'name'     : line_item.title,
                                                'price'    : (line_item.price/100),
                                                'quantity' : line_item.quantity
                                            }
                                        })
                                    }
                                    __DL__.cart = cart;
                                    collection_cartIDs = [];
                                    collection_matchIDs = [];
                                    collection_addtocart = [];
                                    for (var i = __DL__.cart.products.length - 1; i >= 0; i--) {
                                        var x = parseFloat(__DL__.cart.products[i].variant);
                                        collection_cartIDs.push(x);
                                    }
                                });

                                function __DL__addtocart(){



                                    dataLayer.push(product, {
                                        'pageType' : 'Add to Cart',
                                        'event'    : 'Add to Cart'
                                    });

                                    if (__DL__.debug) {
                                        console.log("Add to Cart"+" :"+JSON.stringify(product, null, " "));
                                    }

                                    // if dynamic cart is TRUE
                                    if (__DL__.dynamicCart) {
                                        console.log("dynamic");
                                        var cartCheck = setInterval(function () {
                                            // begin check interval
                                            if ($(__DL__.cartVisableSelector).length > 0) {
                                                // check visible selectors
                                                clearInterval(cartCheck);
                                                mapJSONcartData();
                                                $(__DL__.removeCartTrigger).on('click', function (event) {
                                                    // remove from cart
                                                    var link = $(this).attr("href");
                                                    jQuery.getJSON(link, function (response) {
                                                        // get Json response
                                                        __DL__.removeCart = response;
                                                        var removeFromCart = {
                                                            'products': __DL__.removeCart.items.map(function (line_item) {
                                                                return {
                                                                    'id'       : line_item.id,
                                                                    'sku'      : line_item.sku,
                                                                    'variant'  : line_item.variant_id,
                                                                    'name'     : line_item.title,
                                                                    'price'    : (line_item.price/100),
                                                                    'quantity' : line_item.quantity
                                                                }
                                                            }),
                                                            'pageType' : 'Remove from Cart',
                                                            'event'    : 'Remove from Cart'
                                                        };
                                                        dataLayer.push(removeFromCart);
                                                        if (__DL__.debug) {
                                                            console.log("Cart"+" :"+JSON.stringify(removeFromCart, null, " "));
                                                        }
                                                    });
                                                });
                                            }
                                        }, 500);
                                    }
                                }

                                $(document).on('click', __DL__.cartTriggers, function() {
                                    __DL__addtocart();
                                });

                                }); // document ready
                            }
                        }, 500);

从购物车中删除 Link

<a href="#" data-href="/cart/change?line=1&amp;quantity=0" class="tests cart-item__remove icon-fallback">
    <i class="icon icon--close" aria-hidden="true"> </i>
    <span class="icon-fallback__text">Remove</span>
</a>

初始数据层推送(第一次从购物车中删除 Link 单击)

{
  event: "Cart",
  gtm: {uniqueEventId: XXX, start: XXXXXXX},
  logState: "Logged Out",
  firstLog: false,
  customerEmail: null,
  timestamp: 1626795802651,
  currency: "USD",
  pageType: "Cart",
  products: [
    {
      id: XXXX,
      sku: "XXX",
      variant: XXX,
      name: "XXXX",
      price: 20,
      quantity: 1
    }
  ],
  necessaryTags: true,
  performanceTags: true,
  functionalTags: true,
  targettingTags: true
}

第二次数据层推送(第二次从购物车中删除Link点击)

{
  event: "Remove from Cart",
  gtm: {uniqueEventId: XXX, start: XXXXXX},
  logState: "Logged Out",
  firstLog: false,
  timestamp: 1626796193806,
  currency: "USD",
  pageType: "Remove from Cart",
  products: [
    {
      id: XXXX,
      sku: "XXX",
      variant: XXX,
      name: "XXXX",
      price: 20,
      quantity: 1
    }
  ],
  necessaryTags: true,
  performanceTags: false,
  functionalTags: false,
  targettingTags: false
}

在此先感谢您的帮助!

事实证明,有一个第 3 方 Shopify 应用劫持了购物车表单提交事件并强制重新加载购物车页面。虽然这不能解决我的问题,但它确实回答了 post.

中的问题