feat: 兼容在app上页面滚动与键盘问题
This commit is contained in:
@@ -33,6 +33,7 @@
|
||||
confirm-type="send"
|
||||
v-model="inputMessage"
|
||||
auto-height
|
||||
:focus="isFocused"
|
||||
:confirm-hold="true"
|
||||
:placeholder="placeholder"
|
||||
:show-confirm-bar="false"
|
||||
@@ -322,20 +323,28 @@ const handleTouchEnd = () => {
|
||||
|
||||
// 手动聚焦输入框
|
||||
const focusInput = () => {
|
||||
if (textareaRef.value) {
|
||||
textareaRef.value.focus();
|
||||
}
|
||||
isFocused.value = true;
|
||||
nextTick(() => {
|
||||
if (textareaRef.value) {
|
||||
textareaRef.value.focus();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 手动失焦输入框
|
||||
const blurInput = () => {
|
||||
isFocused.value = false;
|
||||
if (textareaRef.value) {
|
||||
textareaRef.value.blur();
|
||||
}
|
||||
|
||||
nextTick(() => {
|
||||
uni.hideKeyboard();
|
||||
});
|
||||
};
|
||||
|
||||
// 暴露方法给父组件
|
||||
defineExpose({ focusInput });
|
||||
defineExpose({ focusInput, blurInput });
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<view class="flex flex-col h-screen relative">
|
||||
<view class="flex flex-col h-screen relative overflow-hidden">
|
||||
<!-- 顶部自定义导航栏 -->
|
||||
<view class="header absolute top-0 left-0 w-full z-10" :style="{ paddingTop: statusBarHeight + 'px' }">
|
||||
<ChatTopNavBar
|
||||
@@ -21,19 +21,31 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-show="tabIndex === 0" class="flex-full overflow-hidden scroll-y">
|
||||
<Discovery />
|
||||
<view
|
||||
v-show="tabIndex === 0"
|
||||
class="main-scroll-area flex-full overflow-hidden min-height-0"
|
||||
@touchstart.capture="handleScrollAreaTouchStart"
|
||||
@touchstart="handleScrollAreaTouchStart"
|
||||
@touchmove="handleScrollAreaTouchMove"
|
||||
>
|
||||
<Discovery
|
||||
@scroll-touch-start="handleScrollAreaTouchStart"
|
||||
@scroll-touch="handleScrollAreaTouchMove"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<!-- 消息列表(可滚动区域) -->
|
||||
<scroll-view
|
||||
v-show="tabIndex === 1"
|
||||
class="main flex-full overflow-hidden scroll-y"
|
||||
class="main main-scroll-area flex-full overflow-hidden min-height-0"
|
||||
scroll-y
|
||||
:scroll-top="scrollTop"
|
||||
:scroll-with-animation="true"
|
||||
@scroll="handleScroll"
|
||||
@scrolltolower="handleScrollToLower"
|
||||
@touchstart.capture="handleScrollAreaTouchStart"
|
||||
@touchstart="handleScrollAreaTouchStart"
|
||||
@touchmove="handleScrollAreaTouchMove"
|
||||
>
|
||||
|
||||
<view
|
||||
@@ -195,7 +207,7 @@
|
||||
|
||||
<script setup>
|
||||
import { onMounted, nextTick, onUnmounted, ref } from "vue";
|
||||
import { onLoad } from "@dcloudio/uni-app";
|
||||
import { onLoad, onReady } from "@dcloudio/uni-app";
|
||||
import {
|
||||
SWITCH_TO_COMPANION_TAB,
|
||||
SWITCH_TO_DISCOVERY_TAB,
|
||||
@@ -271,6 +283,8 @@ const inputMessage = ref("");
|
||||
|
||||
/// 是否自动滚动到底部 (人工手动向上滚动时设为false)
|
||||
const isAutoScroll = ref(true);
|
||||
let lastHideKeyboardAt = 0;
|
||||
let lastScrollTouchAt = 0;
|
||||
|
||||
/// agentId 首页接口中获取
|
||||
const agentId = ref("1");
|
||||
@@ -348,10 +362,46 @@ const handleKeyboardHide = () => {
|
||||
holdKeyboard.value = false;
|
||||
};
|
||||
|
||||
const hideKeyboardByScroll = () => {
|
||||
const now = Date.now();
|
||||
if (now - lastHideKeyboardAt < 300) return;
|
||||
lastHideKeyboardAt = now;
|
||||
|
||||
holdKeyboard.value = false;
|
||||
holdKeyboardFlag.value = true;
|
||||
isKeyboardShow.value = false;
|
||||
|
||||
if (inputAreaRef.value && inputAreaRef.value.blurInput) {
|
||||
inputAreaRef.value.blurInput();
|
||||
}
|
||||
|
||||
uni.hideKeyboard();
|
||||
|
||||
// #ifdef APP-PLUS
|
||||
if (typeof plus !== "undefined" && plus.key && plus.key.hideSoftKeybord) {
|
||||
plus.key.hideSoftKeybord();
|
||||
}
|
||||
// #endif
|
||||
};
|
||||
|
||||
const handleScrollAreaTouchStart = () => {
|
||||
lastScrollTouchAt = Date.now();
|
||||
hideKeyboardByScroll();
|
||||
};
|
||||
|
||||
const handleScrollAreaTouchMove = () => {
|
||||
lastScrollTouchAt = Date.now();
|
||||
hideKeyboardByScroll();
|
||||
};
|
||||
|
||||
// 处理用户滚动事件
|
||||
const welcomeHeight = ref(0);
|
||||
let lastScrollTop = 0;
|
||||
const handleScroll = (e) => {
|
||||
if (Date.now() - lastScrollTouchAt < 1000) {
|
||||
hideKeyboardByScroll();
|
||||
}
|
||||
|
||||
const detail = e.detail;
|
||||
topNavBarRef.value.show = parseInt(detail.scrollTop) > welcomeHeight.value;
|
||||
|
||||
@@ -484,6 +534,21 @@ onLoad(() => {
|
||||
});
|
||||
});
|
||||
|
||||
onReady(() => {
|
||||
// #ifdef APP-PLUS
|
||||
const pages = getCurrentPages();
|
||||
const currentPage = pages[pages.length - 1];
|
||||
const currentWebview = currentPage && currentPage.$getAppWebview && currentPage.$getAppWebview();
|
||||
|
||||
if (currentWebview && currentWebview.setStyle) {
|
||||
currentWebview.setStyle({
|
||||
bounce: "none",
|
||||
scrollIndicator: "none",
|
||||
});
|
||||
}
|
||||
// #endif
|
||||
});
|
||||
|
||||
// token存在,初始化数据
|
||||
const initHandler = () => {
|
||||
console.log("initHandler");
|
||||
@@ -1229,4 +1294,11 @@ const resetConfig = () => {
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
<style lang="scss" scoped>
|
||||
.main-scroll-area {
|
||||
flex-basis: 0;
|
||||
height: 0;
|
||||
min-height: 0;
|
||||
overscroll-behavior-y: contain;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -9,7 +9,14 @@
|
||||
/>
|
||||
</view>
|
||||
|
||||
<scroll-view class="flex-full border-box min-height-0" scroll-y show-scrollbar="false">
|
||||
<scroll-view
|
||||
class="discovery-scroll flex-full border-box min-height-0"
|
||||
scroll-y
|
||||
show-scrollbar="false"
|
||||
@touchstart="emitScrollTouchStart"
|
||||
@touchmove="emitScrollTouch"
|
||||
@scroll="emitScrollTouch"
|
||||
>
|
||||
<CardSwiper v-if="discoveryCards.length > 0" :list="discoveryCards" @didSelectItem="handleCardClick" />
|
||||
|
||||
<QuickQuestions v-if="discoveryQuickQuestions.length > 0" :list="discoveryQuickQuestions" @didSelectItem="handleQuickQuestionClick" />
|
||||
@@ -42,6 +49,15 @@ const activeIndex = ref(0);
|
||||
const discoveryTabs = ref([]);
|
||||
const discoveryCards = ref([]);
|
||||
const discoveryQuickQuestions = ref([]);
|
||||
const emit = defineEmits(["scroll-touch-start", "scroll-touch"]);
|
||||
|
||||
const emitScrollTouchStart = () => {
|
||||
emit("scroll-touch-start");
|
||||
};
|
||||
|
||||
const emitScrollTouch = () => {
|
||||
emit("scroll-touch");
|
||||
};
|
||||
|
||||
/// tabs 切换事件
|
||||
const handleTabChange = ({ tab, idx }) => {
|
||||
@@ -188,5 +204,10 @@ onMounted(() => {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
.discovery-scroll {
|
||||
flex-basis: 0;
|
||||
height: 0;
|
||||
min-height: 0;
|
||||
overscroll-behavior-y: contain;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
<template>
|
||||
<view class="w-full h-screen bg-liner">
|
||||
<view class="index-page w-full h-screen overflow-hidden bg-liner">
|
||||
<ChatMainList />
|
||||
|
||||
<!-- 日历组件 -->
|
||||
<Calender
|
||||
:visible="calendarVisible"
|
||||
mode="single"
|
||||
:default-value="selectedDate"
|
||||
@close="handleCalendarClose"
|
||||
@select="handleDateSelect"
|
||||
/>
|
||||
|
||||
<!-- 更多服务 -->
|
||||
<MoreService />
|
||||
|
||||
<!-- 抽屉组件 -->
|
||||
<DrawerSection ref="drawerRef" @close="closeDrawer" />
|
||||
</view>
|
||||
|
||||
<!-- 日历组件 -->
|
||||
<Calender
|
||||
:visible="calendarVisible"
|
||||
mode="single"
|
||||
:default-value="selectedDate"
|
||||
@close="handleCalendarClose"
|
||||
@select="handleDateSelect"
|
||||
/>
|
||||
|
||||
<!-- 更多服务 -->
|
||||
<MoreService />
|
||||
|
||||
<!-- 抽屉组件 -->
|
||||
<DrawerSection ref="drawerRef" @close="closeDrawer" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
@@ -88,6 +88,12 @@ onUnmounted(() => {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.index-page {
|
||||
position: relative;
|
||||
min-height: 0;
|
||||
overscroll-behavior: none;
|
||||
}
|
||||
|
||||
.top {
|
||||
margin-top: 150px;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user