x-显示基于父元素 class in Alpine.js 的元素
x-show elements based on parent element class in Alpine.js
在我的 WooCommerce 主题中,我想在 WooCommerce 使用 AJAX 向元素动态添加“正在加载”class 时显示微调器图标。
我尝试使用 Alpine.js 的 $el 属性 来检索当前的 DOM 节点,但这不起作用。它也不是 'watching' 的 classList of .
如何使用 Alpine.js 完成此操作?
<button type="submit" name="add-to-cart" value="<?php echo esc_attr( $product->get_id() ); ?>" class="ajax_add_to_cart add_to_cart_button single_add_to_cart_button button alt flex justify-center" data-product_id="<?php echo get_the_ID(); ?>">
<!-- Spinner Icon -->
<svg x-show="$el.parentElement.classList.contains('loading')" class="animate-spin py-1 h-7 w-7 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
...
</svg>
<!-- Toevoegen aan winkelmand -->
<span x-show="$el.parentElement.classList.contains('!loading')">
<?php echo esc_html( $product->single_add_to_cart_text() ); ?>
</span>
</button>
深入研究 WooCommerce source code 发现它使用 jQuery 事件系统,因此我们必须在 jQuery 和 Alpine.js 之间创建一个小事件总线。这两个事件分别是 AJAX 调用之前调用的 adding_to_cart
和 AJAX 调用成功后触发的 added_to_cart
事件(即产品已添加到购物车) .
让我们调用事件总线 catchWooEvents
:
<script>
document.addEventListener('alpine:init', () => {
Alpine.data('catchWooEvents', () => ({
loading: false,
init() {
$(document.body).on('adding_to_cart', (event, button, data) => {
this.loading = true
})
$(document.body).on('added_to_cart', (fragments, cart_hash, button) => {
this.loading = false
})
}
}))
})
</script>
我们有一个新变量 loading
在两个事件之间处于活动状态。您会看到我们在 init()
中使用了 jQuery 的 $.on()
函数来捕获 jQuery 事件,但随后我们操纵了一个 Alpine.js 变量。
修改按钮示例:
<div x-data="catchWooEvents">
<button type="submit" name="add-to-cart" value="<?php echo esc_attr( $product->get_id() ); ?>" class="ajax_add_to_cart add_to_cart_button single_add_to_cart_button button alt flex justify-center" data-product_id="<?php echo get_the_ID(); ?>">
<!-- Spinner Icon -->
<svg x-show="loading" class="animate-spin py-1 h-7 w-7 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
...
</svg>
<!-- Toevoegen aan winkelmand -->
<span x-show="!loading">
<?php echo esc_html( $product->single_add_to_cart_text() ); ?>
</span>
</button>
</div>
我们有一个新的父 div 元素,我们在其中应用了 catchWooEvents
组件,因此多个子按钮可以共享加载状态。在 x-show
属性中,loading
变量现在是反应式的。
注意:catchWooEvents
的定义必须放在jQuery脚本行之后。
在我的 WooCommerce 主题中,我想在 WooCommerce 使用 AJAX 向元素动态添加“正在加载”class 时显示微调器图标。
我尝试使用 Alpine.js 的 $el 属性 来检索当前的 DOM 节点,但这不起作用。它也不是 'watching' 的 classList of .
如何使用 Alpine.js 完成此操作?
<button type="submit" name="add-to-cart" value="<?php echo esc_attr( $product->get_id() ); ?>" class="ajax_add_to_cart add_to_cart_button single_add_to_cart_button button alt flex justify-center" data-product_id="<?php echo get_the_ID(); ?>">
<!-- Spinner Icon -->
<svg x-show="$el.parentElement.classList.contains('loading')" class="animate-spin py-1 h-7 w-7 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
...
</svg>
<!-- Toevoegen aan winkelmand -->
<span x-show="$el.parentElement.classList.contains('!loading')">
<?php echo esc_html( $product->single_add_to_cart_text() ); ?>
</span>
</button>
深入研究 WooCommerce source code 发现它使用 jQuery 事件系统,因此我们必须在 jQuery 和 Alpine.js 之间创建一个小事件总线。这两个事件分别是 AJAX 调用之前调用的 adding_to_cart
和 AJAX 调用成功后触发的 added_to_cart
事件(即产品已添加到购物车) .
让我们调用事件总线 catchWooEvents
:
<script>
document.addEventListener('alpine:init', () => {
Alpine.data('catchWooEvents', () => ({
loading: false,
init() {
$(document.body).on('adding_to_cart', (event, button, data) => {
this.loading = true
})
$(document.body).on('added_to_cart', (fragments, cart_hash, button) => {
this.loading = false
})
}
}))
})
</script>
我们有一个新变量 loading
在两个事件之间处于活动状态。您会看到我们在 init()
中使用了 jQuery 的 $.on()
函数来捕获 jQuery 事件,但随后我们操纵了一个 Alpine.js 变量。
修改按钮示例:
<div x-data="catchWooEvents">
<button type="submit" name="add-to-cart" value="<?php echo esc_attr( $product->get_id() ); ?>" class="ajax_add_to_cart add_to_cart_button single_add_to_cart_button button alt flex justify-center" data-product_id="<?php echo get_the_ID(); ?>">
<!-- Spinner Icon -->
<svg x-show="loading" class="animate-spin py-1 h-7 w-7 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
...
</svg>
<!-- Toevoegen aan winkelmand -->
<span x-show="!loading">
<?php echo esc_html( $product->single_add_to_cart_text() ); ?>
</span>
</button>
</div>
我们有一个新的父 div 元素,我们在其中应用了 catchWooEvents
组件,因此多个子按钮可以共享加载状态。在 x-show
属性中,loading
变量现在是反应式的。
注意:catchWooEvents
的定义必须放在jQuery脚本行之后。