释放双眼,带上耳机,听听看~!
使用自定义app调用shopify搜索代码
apikey和店铺定制替换,修改css即可使用
<style>
/* Add your styles here */
#search-results {
display: none;
}
#clear-search {
display: none;
cursor: pointer;
}
.show-results {
display: flex !important;
}
.predictive-search {
width: 100%;
z-index:999;
padding: 20px 30px 20px;
border-radius: 8px;
flex-direction: column;
gap: 24px;
box-shadow: 0 5px 5px 0 rgba(0, 0, 0, 0.1);
overflow-y: scroll;
max-height: 66vh;
}
.predictive-result {
display: flex;
gap: 16px;
}
.predictive-result__media {
width:60px;
}
.search__reset {
right: 12px;
padding: 10px;
}
@media (max-width: 768.98px) {
.predictive-search {
gap: 12px;
}
.predictive-result__media {
width:120px;
}
}
</style>
<div class="predictive-search absolute bg-theme-bg text-theme-text text-start" id="search-results"></div>
<script>
document.addEventListener('DOMContentLoaded', function () {
const searchInput = document.getElementById('header-search');
const searchResults = document.getElementById('search-results');
const clearSearch = document.getElementById('clear-search');
searchInput.addEventListener('input', debounce(handleInput));
document.addEventListener('click', handleDocumentClick);
searchInput.addEventListener('focus', function() {
// Trigger search when the input field is focused
handleInput();
});
// 关闭按钮点击事件处理函数
clearSearch.addEventListener('click', function() {
searchInput.value = ''; // 清除输入内容
searchResults.classList.remove('show-results'); // 关闭搜索结果
clearSearch.style.display = 'none'; // 隐藏关闭按钮
});
function handleInput() {
const searchTerm = searchInput.value.trim();
if (!searchTerm) {
searchResults.classList.remove('show-results');
return;
}
// 如果输入框有内容,显示关闭按钮,否则隐藏
clearSearch.style.display = searchInput.value.trim() !== '' ? 'block' : 'none';
// Replace 'your-storefront-access-token' with your actual storefront access token
const storefrontAccessToken = 'a081beb6cae8e7ff8a48b21bafe1a39e';
// Construct the GraphQL query for product search with additional fields (image, price, and URL)
const query = `
{
products(query: "${searchTerm}", first: 100) {
edges {
node {
title
handle
featuredImage {
originalSrc
}
totalInventory
availableForSale
onlineStoreUrl
variants(first: 1) {
edges {
node {
priceV2 {
amount
currencyCode
}
compareAtPriceV2 {
amount
currencyCode
}
}
}
}
}
}
}
}
`;
// Make a request to Shopify Storefront API
fetch('https://cam2-limited.myshopify.com/api/2023-10/graphql.json', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Shopify-Storefront-Access-Token': storefrontAccessToken,
},
body: JSON.stringify({ query }),
})
.then(response => response.json())
.then(data => {
const results = data.data.products.edges
.filter(edge => edge.node.onlineStoreUrl !== null && edge.node.totalInventory > 0) // 过滤掉 不在线销售的商品 和 库存为 0 的商品
.map(edge => {
const product = edge.node;
const totalInventory = edge.node.totalInventory;
const availableForSale = edge.node.availableForSale;
const onlineStoreUrl = edge.node.onlineStoreUrl;
const imageUrl = product.featuredImage ? product.featuredImage.originalSrc : '';
const price = product.variants.edges[0]?.node.priceV2.amount;
const compareAtPrice = product.variants.edges[0]?.node.compareAtPriceV2?.amount;
const currencyCode = product.variants.edges[0]?.node.priceV2.currencyCode;
const productUrl = `/products/${product.handle}`;
return {
title: product.title,
totalInventory,
availableForSale,
onlineStoreUrl,
imageUrl,
price: `${price} ${currencyCode}`,
compareAtPrice: compareAtPrice ? `${compareAtPrice} ${currencyCode}` : null,
productUrl,
};
});
renderResults(results);
})
.catch(error => console.error('Error fetching data:', error));
}
function renderResults(results) {
const slicedResults = results.slice(0, 8); //截取只输出8个
if (slicedResults.length > 0) {
const resultsHTML = slicedResults.map(result => `
<div class="predictive-search__item" role="option" availableForSale="${result.availableForSale}" totalInventory="${result.totalInventory}" productUrl="${result.productUrl}">
<a class="predictive-result flex items-start focus-inset js-search-link" href="${result.onlineStoreUrl}" {% if settings.preload_links %} data-instant{% endif %}>
<div class="predictive-result__media media relative">
<img width="60" class="predictive-result__media" src="${result.imageUrl}" alt="${result.title}">
</div>
<div class="predictive-result__info flex-auto">
<h6>${result.title}</h6>
<div class="price price--on-sale">
<strong class="price__current">${result.price}</strong>
${result.compareAtPrice ? `<s class="price__was">${result.compareAtPrice}</s>` : ''}
</div>
</div>
</a>
</div>
`).join('');
searchResults.innerHTML = resultsHTML;
searchResults.classList.add('show-results');
} else {
searchResults.classList.remove('show-results');
}
}
function debounce(fn, wait = 300) {
let timeout;
return function (...args) {
clearTimeout(timeout);
timeout = setTimeout(() => fn.apply(this, args), wait);
};
}
function handleDocumentClick(event) {
// Check if the click is outside the search input and results
if (!searchInput.contains(event.target) && !searchResults.contains(event.target)) {
searchResults.classList.remove('show-results');
}
}
});
</script>
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。