Browse Source

修复搜索框滑动隐藏效果,实现渐进式隐藏和高度收缩

pull/1/head
Trae AI 2 months ago
parent
commit
249dc32e26
  1. 72
      pages/index/index.js
  2. 22
      pages/index/index.wxml
  3. 52
      pages/index/index.wxss

72
pages/index/index.js

@ -25,6 +25,9 @@ Page({
searchSectionVisible: true, searchSectionVisible: true,
lastScrollTop: 0, lastScrollTop: 0,
isScrollLocked: false, isScrollLocked: false,
searchSectionOpacity: 1,
searchSectionTransform: 0,
isSearchBarFullyHidden: false,
// 回到顶部按钮 // 回到顶部按钮
showBackToTop: false, showBackToTop: false,
@ -604,11 +607,13 @@ Page({
return { leftColumnGoods: leftColumn, rightColumnGoods: rightColumn } return { leftColumnGoods: leftColumn, rightColumnGoods: rightColumn }
}, },
// 搜索输入 // 搜索输入(实时搜索)
onSearchInput: function(e) { onSearchInput: function(e) {
this.setData({ this.setData({
searchKeyword: e.detail.value searchKeyword: e.detail.value
}) })
// 实时应用筛选条件
this.searchGoods()
}, },
// 搜索商品 // 搜索商品
@ -637,22 +642,23 @@ Page({
}) })
}, },
// 选择地区 // 选择地区(实时更新)
selectRegion: function(e) { selectRegion: function(e) {
const region = e.currentTarget.dataset.region const region = e.currentTarget.dataset.region
this.setData({
selectedRegion: region
})
},
// 确认地区选择
confirmRegion: function() {
// 重新显示tabBar // 重新显示tabBar
const app = getApp(); const app = getApp();
if (app && app.globalData) { if (app && app.globalData) {
app.globalData.showTabBar = true; app.globalData.showTabBar = true;
} }
// 应用筛选条件
this.setData({
selectedRegion: region,
showRegionPicker: false
})
// 重新筛选商品
const filteredGoods = this.applyFilters(this.data.goods) const filteredGoods = this.applyFilters(this.data.goods)
const groupedGoods = this.groupGoodsForStaggeredLayout(filteredGoods) const groupedGoods = this.groupGoodsForStaggeredLayout(filteredGoods)
const { leftColumnGoods, rightColumnGoods } = this.distributeToColumns(filteredGoods) const { leftColumnGoods, rightColumnGoods } = this.distributeToColumns(filteredGoods)
@ -660,8 +666,7 @@ Page({
filteredGoods: filteredGoods, filteredGoods: filteredGoods,
groupedGoods: groupedGoods, groupedGoods: groupedGoods,
leftColumnGoods: leftColumnGoods, leftColumnGoods: leftColumnGoods,
rightColumnGoods: rightColumnGoods, rightColumnGoods: rightColumnGoods
showRegionPicker: false
}) })
}, },
@ -782,39 +787,44 @@ Page({
onScroll: function(e) { onScroll: function(e) {
const { scrollTop } = e.detail; const { scrollTop } = e.detail;
if (this.data.isScrollLocked) { let searchSectionOpacity = 1;
this.setData({ lastScrollTop: scrollTop }); let searchSectionTransform = 0;
return; let isSearchBarFullyHidden = false;
}
const scrollDirection = scrollTop > this.data.lastScrollTop ? 'down' : 'up'; if (scrollTop > 50) {
const scrollDelta = Math.abs(scrollTop - this.data.lastScrollTop); // 当滚动距离超过50rpx时,开始逐渐隐藏
const hideProgress = Math.min((scrollTop - 50) / 100, 1); // 0-1的隐藏进度
searchSectionOpacity = 1 - hideProgress;
searchSectionTransform = -20 * hideProgress;
if (scrollDelta < 10) { // 当隐藏进度达到100%时,完全隐藏并收缩高度
this.setData({ lastScrollTop: scrollTop }); if (hideProgress >= 1) {
return; isSearchBarFullyHidden = true;
}
} }
if (scrollDirection === 'down' && scrollTop > 100 && this.data.searchSectionVisible) { // 当滚动回到顶部时,重置所有状态
this.setData({ searchSectionVisible: false, isScrollLocked: true }); if (scrollTop <= 50) {
setTimeout(() => { searchSectionOpacity = 1;
this.setData({ isScrollLocked: false }); searchSectionTransform = 0;
}, 300); isSearchBarFullyHidden = false;
} else if (scrollDirection === 'up' && !this.data.searchSectionVisible && scrollTop < 50) {
this.setData({ searchSectionVisible: true, isScrollLocked: true });
setTimeout(() => {
this.setData({ isScrollLocked: false });
}, 300);
} }
// 更新搜索框状态和样式
this.setData({
searchSectionOpacity: searchSectionOpacity,
searchSectionTransform: searchSectionTransform,
isSearchBarFullyHidden: isSearchBarFullyHidden,
lastScrollTop: scrollTop
});
// 回到顶部按钮显示逻辑
if (scrollTop > 300 && !this.data.showBackToTop) { if (scrollTop > 300 && !this.data.showBackToTop) {
this.setData({ showBackToTop: true }); this.setData({ showBackToTop: true });
} else if (scrollTop <= 300 && this.data.showBackToTop) { } else if (scrollTop <= 300 && this.data.showBackToTop) {
this.setData({ showBackToTop: false }); this.setData({ showBackToTop: false });
} }
this.setData({ lastScrollTop: scrollTop });
const { scrollHeight, clientHeight } = e.detail; const { scrollHeight, clientHeight } = e.detail;
const distanceToBottom = scrollHeight - scrollTop - clientHeight; const distanceToBottom = scrollHeight - scrollTop - clientHeight;

22
pages/index/index.wxml

@ -1,9 +1,14 @@
<view class="container"> <view class="container">
<!-- 顶部搜索区域容器 -->
<view
class="top-section {{isSearchBarFullyHidden ? 'top-hidden' : ''}}"
style="opacity: {{searchSectionOpacity}}; transform: translateY({{searchSectionTransform}}rpx);"
>
<!-- 标题 --> <!-- 标题 -->
<view class="title {{searchSectionVisible ? '' : 'title-hidden'}}">专业的鸡蛋现货交易平台</view> <view class="title">专业的鸡蛋现货交易平台</view>
<!-- 搜索区域 --> <!-- 搜索区域 -->
<view class="search-section {{searchSectionVisible ? 'search-visible' : 'search-hidden'}}"> <view class="search-section">
<view class="search-bar"> <view class="search-bar">
<view class="search-input-wrapper"> <view class="search-input-wrapper">
<!-- 将地区选择器放在最左边 --> <!-- 将地区选择器放在最左边 -->
@ -24,6 +29,7 @@
<button class="search-button" bindtap="searchGoods">搜索</button> <button class="search-button" bindtap="searchGoods">搜索</button>
</view> </view>
</view> </view>
</view>
<!-- 地区选择器弹窗 --> <!-- 地区选择器弹窗 -->
<view wx:if="{{showRegionPicker}}" class="region-picker-overlay" bindtap="toggleRegionPicker"> <view wx:if="{{showRegionPicker}}" class="region-picker-overlay" bindtap="toggleRegionPicker">
@ -40,7 +46,6 @@
{{item}} {{item}}
</view> </view>
</view> </view>
<button class="confirm-region-btn" bindtap="confirmRegion">确定</button>
</view> </view>
</view> </view>
@ -195,6 +200,13 @@
</view> </view>
</view> </view>
<!-- 无搜索结果提示 -->
<view wx:if="{{filteredGoods.length === 0 && !isLoading}}" class="empty-goods">
<text class="empty-icon">🔍</text>
<text class="empty-text">暂无相关商品</text>
<text class="empty-hint">试试调整搜索条件或地区筛选</text>
</view>
<!-- 正常商品列表 --> <!-- 正常商品列表 -->
<view <view
class="waterfall-item" class="waterfall-item"
@ -202,7 +214,7 @@
wx:key="id" wx:key="id"
data-item="{{item}}" data-item="{{item}}"
bindtap="viewGoodsDetail" bindtap="viewGoodsDetail"
wx:if="{{!item.isAd}}" wx:if="{{!item.isAd && filteredGoods.length > 0}}"
> >
<view class="product-card"> <view class="product-card">
<view class="product-image-wrapper"> <view class="product-image-wrapper">
@ -260,7 +272,7 @@
wx:key="id" wx:key="id"
data-item="{{item}}" data-item="{{item}}"
bindtap="viewGoodsDetail" bindtap="viewGoodsDetail"
wx:if="{{!item.isAd}}" wx:if="{{!item.isAd && filteredGoods.length > 0}}"
> >
<view class="product-card"> <view class="product-card">
<view class="product-image-wrapper"> <view class="product-image-wrapper">

52
pages/index/index.wxss

@ -19,50 +19,38 @@ page {
background-color: #f8f8f8; background-color: #f8f8f8;
} }
/* 标题样式 */ /* 顶部搜索区域容器 */
.title { .top-section {
font-size: 36rpx;
font-weight: bold;
margin: 20rpx;
color: #333;
text-align: center;
flex-shrink: 0; flex-shrink: 0;
transition: all 0.3s ease; padding: 10rpx 0;
margin-bottom: 20rpx;
overflow: hidden;
transition: all 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
will-change: opacity, transform, padding, margin, max-height;
} }
.title-hidden { /* 顶部搜索区域完全隐藏状态 - 用于收缩高度 */
opacity: 0; .top-hidden {
transform: translateY(-20rpx); max-height: 0;
height: 0;
margin: 0;
padding: 0; padding: 0;
overflow: hidden; margin-bottom: 0;
pointer-events: none;
} }
/* 搜索区域样式 */ /* 标题样式 */
.search-section { .title {
font-size: 36rpx;
font-weight: bold;
margin: 10rpx 20rpx;
color: #333;
text-align: center;
flex-shrink: 0; flex-shrink: 0;
transition: all 0.3s ease;
}
.search-visible {
opacity: 1;
transform: translateY(0);
height: auto;
}
.search-hidden {
opacity: 0;
transform: translateY(-100%);
height: 0;
overflow: hidden;
} }
/* 搜索区域样式 */ /* 搜索区域样式 */
.search-section { .search-section {
width: 100%; width: 100%;
margin: 0 20rpx 20rpx 20rpx; margin: 0 30rpx 0 10rpx;
flex: 0 1 auto;
box-sizing: border-box; box-sizing: border-box;
} }

Loading…
Cancel
Save