Online Store 2.1 浏览器标准事件

在 Online Store 2.1 主题中,SHOPLINE 是基于标准浏览器事件来处理这个通信。如果你用的是 Online Store 2.0 & 1.0 的主题,可以参考 Online Store 2.0 & 1.0 主题事件

应用场景样例

款式选择

下面是一个款式选择的示例代码

<variant-selects>
<label>
<input type="checkbox" value="blue" name="variant-input-blue" />
blue
</label>
<label>
<input type="checkbox" value="red" name="variant-input-red" />
red
</label>
</variant-selects>

通过 JavaScript 对上面的 HTML 结构给款式选择绑定事件,当选择款式后,会记录选择的款式并在浏览器控制台打印现在已经选择的款式。

class VariantSelects extends HTMLElement {
constructor() {
super();
this.variantInputs = this.querySelectorAll('input[name^="variant-input"]');
this.variantStore = new Set();
this.variantInputs.forEach((variantInput) => {
variantInput.addEventListener('change', (event) => {
const elem = event.target;
if (elem.checked) {
this.variantStore.add(elem.value);
} else {
this.variantStore.delete(elem.value);
}
console.log('variant changed: ', Array.from(this.variantStore));
});
});
}
}
customElements.define('variant-selects', VariantSelects);

商品加购

下面是商品加购的示例代码

<product-form class="product-form" data-default-error-message="{{t 'products.general.no_product_data_found'}}">
{{#form "product" product id=product_form_id}}
<div class="product-form__buttons">
<button
id="{{product_form_id}}-submit"
type="submit"
name="add"
class="product-form__submit button button--full-width button--secondary"
{{#unless product.selected_or_first_available_variant.available}}
disabled
{{/unless}}
>
<span>
{{#if product.selected_or_first_available_variant.available}}
{{t "products.product_list.add_to_cart"}}
{{else}}
{{t "products.general.sold_out"}}
{{/if}}
</span>
{{snippet "loading-overlay-spinner"}}
</button>
{{payment_button}}
</div>
{{/form}}
</product-form>

通过 JavaScript 对上面的 HTML 结构给商品表单的提交按钮绑定点击事件,当点击提交按钮时,会触发商品的加购请求。

class ProductForm extends HTMLElement {
constructor() {
super();
this.submitButton = this.querySelector('[type="submit"]');
this.submitButton.addEventListener('click', this.submitButtonClickHandler.bind(this));
}
// Because the editor hijack the a tag click event, the click event needs to be bound to prevent bubbling
submitButtonClickHandler(e) {
e.preventDefault();
e.stopPropagation();
this.onSubmitHandler();
}
onSubmitHandler() {
if (this.submitButton.classList.contains('disabled') || this.submitButton.classList.contains('loading')) return;

const config = {
method: 'POST',
headers: {
'X-Requested-With': 'XMLHttpRequest',
Accept: `application/json`,
},
};
const formData = new FormData(this.form);
config.body = formData;
fetch(`${window.routes.cart_add_url}`, config)
.then((response) => response.json())
.then((response) => {
// 这里处理加购后的逻辑
})
.finally(() => {
this.submitButton.classList.remove('loading');
});
}
};
customElements.define('product-form', ProductForm);

商品搜索

下面是商品搜索的示例代码

<predictive-search class="main-search__content">
<form action="{{ routes.search_url }}" method="get" class="main-search__form search">
<div class="main-search__field field">
<input
id="main-search-input"
class="main-search__input field__input body3"
type="search"
name="keyword"
value="{{ search.terms }}"
placeholder="{{ t 'general.search.search' }}"
maxlength="255"
autocorrect="off"
autocomplete="off"
autocapitalize="off"
spellcheck="false"
>
<label class="main-search__field-label field__label body3" for="main-search-input">{{ t 'general.search.search' }}</label>
<button class="main-search__submit-button">
{{snippet 'icon-search'}}
</button>
</div>
<div class="predictive-search global-modal-border-shadow" tabindex="-1">
<div class="predictive-search__results" data-predictive-search></div>
<div class="predictive-search__loading-state">
<span class="predictive-search__spinner">
{{ snippet 'icon-loading' }}
</span>
</div>
</div>
</form>
</predictive-search>

通过 JavaScript 对上面的 HTML 结构给搜索表单的输入框、predictive-search 组件绑定了一系列事件:

  • 给表单绑定了 submit 事件,当点击提交表单按钮时,会触发该事件
  • 给搜索输入框绑定了
    • input 事件,当向搜索输入框输入文字时,会触发该事件
    • focus 事件,当鼠标聚焦到搜索输入框时,会触发该事件
  • 给 predictive-search 绑定了
    • focusout 事件,当鼠标离开 predictive-search 组件时,会触发该事件
    • keyup 事件,当在 predictive-search 组件键入文字松开键盘时,会触发该事件
    • keydown 事件,当在 predictive-search 组件按下键盘输入文字时,会触发该事件
class PredictiveSearch extends BaseElement {
constructor() {
super();
this.input = this.querySelector('input[type="search"]');
this.setupEventListeners();
}
get query() {
return this.input.value.trim();
}
setupEventListeners() {
const form = this.querySelector('form.search');
form.addEventListener('submit', this.onFormSubmit.bind(this));
this.input.addEventListener('input', window.debounce(this.onChange.bind(this), 300));
this.input.addEventListener('focus', this.onFocus.bind(this));
this.addEventListener('focusout', this.onFocusOut.bind(this));
this.addEventListener('keyup', this.onKeyup.bind(this));
this.addEventListener('keydown', this.onKeydown.bind(this));
}
onFormSubmit(event) {
if (!this.query.length || this.querySelector('[selected="true"]')) event.preventDefault();
}
onChange() {
// 通过 this.query 获取查询关键字来搜索商品
}
onFocus() {
// 鼠标光标进入输入框
}
onFocusOut() {
// 鼠标光标离开输入框
}
onKeyup() {
// 监听并处理键盘按键事件
}
onKeydown(event) {
if (event.code === 'ArrowUp' || event.code === 'ArrowDown') {
event.preventDefault();
}
}
}
customElements.define('predictive-search', PredictiveSearch);
这篇文章对你有帮助吗?