在 Bricks 中,你可以用动态数据/函数 {woo_add_to_cart} 直接创建一个加购按钮。只要在 WooCommerce > Settings > Products > Add to cart behaviour 里开启 Enable AJAX add to cart buttons on archives(在归档页启用 AJAX 加购按钮),这个按钮就支持 AJAX 了。
在 WooCommerce 设置页开启 AJAX 加购
既然我们在用可视化页面构建器,为什么不直接在构建器里创建按钮,然后随心所欲地样式化、定制它呢?
本教程中,我会把 AJAX 加购按钮放进自定义的产品循环模板(product loop template)里。 想自己搭一个的话,可以先读这篇产品循环模板教程。
我自己的 AJAX 加购按钮
第 1 步:添加 Bricks 按钮元素
重要提示
如果你在跟做我的产品循环教程,记得移除外层包装的链接(Outer wrapper link)。链接套链接、按钮套按钮会搞坏布局。
在产品循环模板里直接加一个 Button 元素即可。
新按钮出现在我的循环底部
在 CONTENT(内容)选项卡里填写文字和图标。LINK 设置中:Link type 选 External URL,URL 不能留空——至少填一个 # 让按钮可点击。最好跟我的设置一样,填一个动态加购 URL(这不影响 AJAX 功能):
URL 不能为空!至少填 # 或照我的设置来
第 2 步:把普通按钮变成 AJAX 加购按钮
到这一步,你的按钮还只是个普通按钮:点击它要么因为锚点 URL(#)跳到页面顶部;要么在按钮 URL 里用 ?add-to-cart=post_id 能成功加购,但那是传统方式,不是 AJAX。
把原生按钮变成 WooCommerce AJAX 加购按钮非常简单——只要加几个 CSS 类和自定义属性就行!
进入按钮的 STYLE(样式)选项卡,把 CSS classes 设为:
add_to_cart_button ajax_add_to_cart
记得类之间用空格分隔
添加以下 Attributes(属性):
- data-quantity:设为 1,这样按钮会给当前产品加 1 件数量到购物车。想动态控制这个值可以用 JavaScript 方案,但本教程不涉及。
- data-product_id:AJAX 加购时的产品 ID。用动态数据 post_id 动态填充。当然要在循环里用,否则 post_id 永远是同一个。不了解的话请看我的 WooCommerce 产品循环模板教程。
- aria-label:用于无障碍(accessibility)。
现在保存并到前端测试一下!
AJAX 生效了!但还需要改进。
能用是能用了,但有两个问题要解决:
- 没有任何「AJAX 处理中/已完成」的视觉提示。
- 对**可变产品(variable product)**来说,可能加购成功了,但加进去的产品没有带上选中的选项。
第 3 步:AJAX 状态提示
我们可以用 jQuery 挂钩 WooCommerce 的事件(WooCommerce 还在用 jQuery)。发起请求时,把 “Add Cart”(加购)文字改成 “Adding”(添加中);AJAX 完成时改成 “Added”(已添加)。
2022 年 8 月 17 日更新:你可以用同一个事件把访客重定向到结算页——当成一个 “Buy Now”(立即购买)按钮来用。
这段 jQuery 在哪里执行都可以,我把代码放在 Bricks > Settings > Custom Code > Body (footer) scripts(页脚脚本)里:
Bricks > Settings > Custom Code > Body (footer) scripts
重要提示
如果你在循环(loop)里,请别用 Code 元素——除非有特殊需求而且你清楚自己在做什么。想想前端会渲染出多少份重复代码吧。
<script>
(($)=>{
$(document).ready(()=>{
// When Adding To Cart
$('body').on('adding_to_cart', (e, button, data)=>{
// Change my Text to "Adding". I use lastChild because firstChild is my Icon
button[0].lastChild.textContent = "Adding..."
});
// When Added To Cart
$('body').on('added_to_cart', (e, fragments, cart_hash, button)=>{
// Change my Text to "Added"
button[0].lastChild.textContent = "Added"
});
})
})(jQuery)
</script>
Buy Now 按钮的 JavaScript 示例
<script>
// Example to redirect visitor to checkout page after add to cart
// Just change your button text to Buy Now if necessary
$('body').on('added_to_cart', (e, fragments, cart_hash, button)=>{
// You can use setTimeout to delay redirection if necessary
setTimeout( function() {
window.location.href = `${window.location.origin}/checkout`
}, 800 )
});
</script>
按钮样式方面,可以借助 WooCommerce 在 AJAX 请求时注入的 loading 和 added 两个 CSS 类——这两个类会加在按钮元素上。
下面是我加在自定义按钮上的 CSS:
root.loading i {
-webkit-animation: spin 1s linear infinite;
animation: spin 1s linear infinite;
}
root.loading i::before {
content: "\e619";
}
root.added i::before {
content: "\e64d"
}
注意我把图标内容改成了 \e619 和 \e64d,因为我用的是 Themify 图标。你可以随意替换成自己的图标。这段 CSS 可以按需调整。spin 旋转动画来自 Bricks 的 frontend.min.css。
到这个阶段,你的按钮应该长这样了:
体验更好了吧?
第 4 步:动态显示按钮
为了避免可变产品通过 AJAX 加购时出错,最好的办法是:对可变产品另外显示一个普通按钮,把访客引导到该可变产品的详情页。
在 AJAX 加购按钮下方再创建一个简单按钮:
新按钮
普通按钮只要把链接设为产品 post_url 即可
产品循环里现在有两个按钮
在 functions.php 里写一个简单函数(或用 WPCodebox 插件),它动态返回 True 或 False:
<?php
function itchy_is_simple_product() {
global $product;
return is_a( $product, 'WC_Product_Simple' );
}
?>
下面两种方法任选其一使用这个函数:
方法 A:条件显示插件(非官方)
我在 2022 年 6 月写了一个 免费的 Bricks 条件显示插件。你可以用它来在构建器模式下显示/隐藏按钮。如果你直接用 MetaBox 或 ACF 自定义字段做条件比较值,这个插件会非常方便。
在 ITCHY ADVANCED 选项卡里配置条件:
方法 B:bricks/element/render 过滤器
如果你更喜欢写代码,把下面代码复制到 functions.php 或用 WPCodeBox 添加。记得把元素 ID 换成你自己的:
<?php
add_filter( 'bricks/element/render', 'itchycode_conditional_display_buttons', 10, 2 );
function itchycode_conditional_display_buttons( $show, $element ) {
// Replace your button IDs here
if( $element->id !== 'qlnmvz' && $element->id !== 'rsipdc') return $show;
return itchy_is_simple_product();
}
去前端检查一下,现在完美了!