|
|
|
|
@ -81,171 +81,4 @@
|
|
|
|
|
// 如果$tourListData可能为null,可以添加默认值
|
|
|
|
|
TourData = TourData || [];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
|
|
|
// 获取DOM元素
|
|
|
|
|
const tourListContainer = document.getElementById('js_tourlist');
|
|
|
|
|
const allCountSpan = document.getElementById('all-count');
|
|
|
|
|
|
|
|
|
|
// 初始化筛选器
|
|
|
|
|
setupFilter('theme-list', 'clear-theme');
|
|
|
|
|
setupFilter('hours-list', 'clear-hours');
|
|
|
|
|
setupFilter('price-list', 'clear-price');
|
|
|
|
|
|
|
|
|
|
// 通用函数:设置筛选列表的点击和清除功能
|
|
|
|
|
function setupFilter(listId, clearBtnId) {
|
|
|
|
|
const list = document.getElementById(listId);
|
|
|
|
|
const clearBtn = document.getElementById(clearBtnId);
|
|
|
|
|
|
|
|
|
|
if (!list || !clearBtn) return;
|
|
|
|
|
|
|
|
|
|
// 点击列表项
|
|
|
|
|
list.addEventListener('click', function(e) {
|
|
|
|
|
const target = e.target.closest('li');
|
|
|
|
|
if (target && e.target.tagName === 'A') {
|
|
|
|
|
target.classList.toggle('active');
|
|
|
|
|
filterAndDisplayTours();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 清除按钮
|
|
|
|
|
clearBtn.addEventListener('click', function() {
|
|
|
|
|
const activeItems = list.querySelectorAll('.active');
|
|
|
|
|
activeItems.forEach(item => {
|
|
|
|
|
item.classList.remove('active');
|
|
|
|
|
});
|
|
|
|
|
filterAndDisplayTours();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 筛选并显示旅游项目
|
|
|
|
|
function filterAndDisplayTours() {
|
|
|
|
|
|
|
|
|
|
// 获取选中的主题
|
|
|
|
|
const selectedThemes = [];
|
|
|
|
|
document.querySelectorAll('#theme-list li.active a').forEach(a => {
|
|
|
|
|
selectedThemes.push(a.getAttribute('data-id'));
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 获取选中的时间范围
|
|
|
|
|
const selectedHourRanges = [];
|
|
|
|
|
document.querySelectorAll('#hours-list li.active a').forEach(a => {
|
|
|
|
|
selectedHourRanges.push(a.getAttribute('data-day'));
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 获取选中的价格范围
|
|
|
|
|
const selectedPriceRanges = [];
|
|
|
|
|
document.querySelectorAll('#price-list li.active a').forEach(a => {
|
|
|
|
|
selectedPriceRanges.push(a.getAttribute('data-price'));
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 筛选旅游数据
|
|
|
|
|
const filteredTours = TourData.filter(tour => {
|
|
|
|
|
|
|
|
|
|
// 检查主题
|
|
|
|
|
const themeMatch = selectedThemes.length === 0 ||
|
|
|
|
|
(tour.extendType && selectedThemes.some(theme =>
|
|
|
|
|
tour.extendType.split(',').includes(theme)));
|
|
|
|
|
|
|
|
|
|
// 检查时间
|
|
|
|
|
const hourMatch = selectedHourRanges.length === 0 ||
|
|
|
|
|
selectedHourRanges.some(range => {
|
|
|
|
|
const [min, max] = range.split('-').map(Number);
|
|
|
|
|
const needTime = parseFloat(tour.needTime) || 0;
|
|
|
|
|
return needTime >= min && needTime <= max;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 检查价格
|
|
|
|
|
const priceMatch = selectedPriceRanges.length === 0 ||
|
|
|
|
|
selectedPriceRanges.some(range => {
|
|
|
|
|
const [min, max] = range.split('-').map(Number);
|
|
|
|
|
// 处理空价格或无效价格情况
|
|
|
|
|
if (tour.price === undefined || tour.price === null || tour.price === "") return false;
|
|
|
|
|
|
|
|
|
|
// 转换价格为数字
|
|
|
|
|
const price = typeof tour.price === 'string'
|
|
|
|
|
? parseFloat(tour.price.replace(/[^0-9.]/g, ''))
|
|
|
|
|
: Number(tour.price);
|
|
|
|
|
|
|
|
|
|
// 检查价格是否在范围内
|
|
|
|
|
return !isNaN(price) && price >= min && price <= max;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return themeMatch && hourMatch && priceMatch;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 更新总计数
|
|
|
|
|
allCountSpan.textContent = filteredTours.length;
|
|
|
|
|
|
|
|
|
|
// 显示筛选结果
|
|
|
|
|
displayTours(filteredTours);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 显示旅游项目
|
|
|
|
|
function displayTours(tours) {
|
|
|
|
|
// 清空现有内容
|
|
|
|
|
tourListContainer.innerHTML = '';
|
|
|
|
|
|
|
|
|
|
// 如果没有结果,显示提示
|
|
|
|
|
if (tours.length === 0) {
|
|
|
|
|
tourListContainer.innerHTML = '<div class="no-results">No tours found matching your criteria.</div>';
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 遍历并添加每个旅游项目
|
|
|
|
|
tours.forEach(tour => {
|
|
|
|
|
// 格式化时间显示
|
|
|
|
|
const needTime = parseFloat(tour.needTime) || 0;
|
|
|
|
|
let timeDisplay = '';
|
|
|
|
|
if (needTime < 1) {
|
|
|
|
|
// 小于1小时显示分钟
|
|
|
|
|
const minutes = Math.round(needTime * 60);
|
|
|
|
|
timeDisplay = `${minutes}-Minutes`;
|
|
|
|
|
} else if (needTime === 1) {
|
|
|
|
|
timeDisplay = '1-Hour';
|
|
|
|
|
} else {
|
|
|
|
|
timeDisplay = `${needTime % 1 === 0 ? needTime : needTime.toFixed(1)}-Hours`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 格式化价格显示
|
|
|
|
|
let priceDisplay = 'Price on request';
|
|
|
|
|
if (tour.price !== undefined && tour.price !== null && tour.price !== "" && tour.price !== 0) {
|
|
|
|
|
const priceNum = typeof tour.price === 'string'
|
|
|
|
|
? parseFloat(tour.price.replace(/[^0-9.]/g, ''))
|
|
|
|
|
: Number(tour.price);
|
|
|
|
|
|
|
|
|
|
if (!isNaN(priceNum) && priceNum > 0) {
|
|
|
|
|
// 只显示整数部分
|
|
|
|
|
priceDisplay = 'US$' + Math.floor(priceNum).toLocaleString('en-US');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const tourHtml = `
|
|
|
|
|
<div class="flex-col border-box">
|
|
|
|
|
<a href="${tour.url || '#'}" rel="nofollow">
|
|
|
|
|
<span class="flag-box"></span>
|
|
|
|
|
<img alt="${tour.title || 'Tour image'}" class="img-responsive" src="${tour.pic || ''}">
|
|
|
|
|
</a>
|
|
|
|
|
<div class="caption">
|
|
|
|
|
<h3><a href="${tour.url || '#'}">${tour.title || 'Untitled Tour'}</a></h3>
|
|
|
|
|
<ul class="card-ul">
|
|
|
|
|
<li class="card-hours">${timeDisplay}</li>
|
|
|
|
|
</ul>
|
|
|
|
|
<div class="caption-btn">
|
|
|
|
|
<p>From <span class="baseprice font24">${priceDisplay}</span></p>
|
|
|
|
|
<p><a aria-label="button" class="btn-base" href="${tour.url || '#'}" rel="nofollow">View More</a></p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
tourListContainer.insertAdjacentHTML('beforeend', tourHtml);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 初始加载时显示所有旅游项目
|
|
|
|
|
filterAndDisplayTours();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</script>
|