为什么我必须触发两次点击事件才能触发正确的数据层?
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&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.
中的问题
上下文
我正在尝试将事件推送到 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&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.
中的问题