H5 如何去掉input[type=time]默认样式中的下拉箭头

本文介绍了一种有效的方法来移除HTML中input[type=time]元素默认显示的下拉箭头,并讨论了自定义时间控件样式的重要性。
试了百度上的很多样式修改,都没有成功,后面加上这个样式就成功去掉了下拉箭头:
-webkit-appearance: none;

手机浏览器默认的input[type=time]样式各有不同,虽然省去了写时间控件的时间,但是感觉并不好用,还是自己自定义控件和样式比较好。

<script setup> import { ref, reactive, onMounted, computed } from 'vue'; import { onShow } from '@dcloudio/uni-app'; // 响应式数据 const surveyList = ref([]); const total = ref(0); const loading = ref(false); const formData = reactive({ dcWjTitle: '', dcId: [], dcDept: '', state: null }); const bdrOptions = ref([]); const bdrLoading = ref(false); const pagination = reactive({ current: 1, size: 10, total: 0 }); // 被测评人选择器相关 const bdrSearchKeyword = ref(''); const showBdrList = ref(false); const filteredBdrOptions = ref([]); const showBdrPlaceholder = ref(true); // 状态选择器相关 const stateOptions = ref([ { label: '全部', value: null }, { label: '已提交', value: 1 }, { label: '未提交', value: 0 } ]); const showStateList = ref(false); // 计算属性 const selectedBdrLabel = computed(() => { if (formData.dcId.length === 0) return ''; const selected = bdrOptions.value.find(b => b.value === formData.dcId[0]); return selected ? selected.label : ''; }); const getStateLabel = (value) => { const state = stateOptions.value.find(s => s.value === value); return state ? state.label : '全部'; }; // 被测评人选择器方法 const handleBdrFocus = () => { showBdrList.value = true; showBdrPlaceholder.value = false; filterBdrOptions(); }; const handleBdrInput = (e) => { bdrSearchKeyword.value = e.detail.value; filterBdrOptions(); }; const handleBdrSelect = (item) => { formData.dcId = [item.value]; showBdrList.value = false; bdrSearchKeyword.value = ''; showBdrPlaceholder.value = false; }; const toggleBdrList = () => { showBdrList.value = !showBdrList.value; if (showBdrList.value) { filterBdrOptions(); } }; // 状态选择器方法 const handleStateSelect = (state) => { formData.state = state.value; showStateList.value = false; }; const toggleStateList = () => { showStateList.value = !showStateList.value; }; // 过滤被测评人选项 const filterBdrOptions = () => { if (!bdrSearchKeyword.value) { filteredBdrOptions.value = [...bdrOptions.value]; return; } const keyword = bdrSearchKeyword.value.toLowerCase(); filteredBdrOptions.value = bdrOptions.value.filter(item => item.label.toLowerCase().includes(keyword) ); }; // 获取问卷数据 const fetchSurveyData = async () => { try { loading.value = true; const token = uni.getStorageSync('token'); if (!token) { uni.showToast({ title: '请先登录', icon: 'none' }); uni.redirectTo({ url: '/pages/login/login' }); return; } const res = await uni.request({ url: 'http://172.26.26.43/dev-api/wjdc/wj/listTx', method: 'GET', data: { pageNum: pagination.current, pageSize: pagination.size, dcWjTitle: formData.dcWjTitle, dcId: formData.dcId.join(','), dcDept: formData.dcDept, state: formData.state }, header: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, timeout: 10000 // 增加超时设置 }); // 完整的响应日志 // console.log('API响应:', res); // 处理不同的响应格式 let responseData = null; // 处理 uni.request 的不同返回值格式 if (Array.isArray(res)) { // uni-app 返回数组格式 [error, response] if (res[0]) throw res[0]; // 如果有错误对象 responseData = res[1].data; } else { // 直接返回对象格式 responseData = res.data; } // 检查响应状态码 if (responseData?.code === 200) { surveyList.value = responseData.rows || []; total.value = responseData.total || 0; pagination.total = responseData.total || 0; } else { // 更详细的错误信息 const errorMsg = responseData?.msg || `API返回非200状态: ${responseData?.code || '未知'}`; throw new Error(errorMsg); } } catch (error) { console.error('请求错误详情:', error); // 更精确的错误分类 let userFriendlyMsg = '加载问卷数据失败'; if (error.errMsg?.includes('timeout')) { userFriendlyMsg = '请求超时,请检查网络连接'; } else if (error.errMsg?.includes('404')) { userFriendlyMsg = 'API地址不存在,请联系管理员'; } else if (error.errMsg?.includes('401')) { userFriendlyMsg = '登录已过期,请重新登录'; uni.redirectTo({ url: '/pages/login/login' }); } else if (error.message) { userFriendlyMsg = error.message; } uni.showToast({ title: userFriendlyMsg, icon: 'none', duration: 3000 }); } finally { loading.value = false; } }; // 清除被测评人选择的方法 const handleClearBdr = (e) => { e.stopPropagation(); // 阻止事件冒泡 formData.dcId = []; bdrSearchKeyword.value = ''; showBdrList.value = false; showBdrPlaceholder.value = true; }; // 获取被测评人列表 const fetchBdrList = async () => { try { const token = uni.getStorageSync('token'); if (!token) { console.warn('未获取到token,跳过获取被测评人列表'); return; } // 打印请求开始信息 // console.log('开始获取被测评人列表...'); const res = await uni.request({ url: 'http://172.26.26.43/dev-api/wjdc/wj/getBdrList', method: 'GET', header: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, timeout: 8000 }); // 详细记录原始响应 // console.log('被测评人API原始响应:', res); // 统一处理uni-app不同平台的响应格式 let response = null; if (Array.isArray(res)) { // 小程序格式 [error, response] if (res[0]) { throw res[0]; } response = res[1]; } else { // H5格式 { data, statusCode, ... } response = res; } // 检查HTTP状态码 if (response.statusCode !== 200) { throw new Error(`HTTP错误: ${response.statusCode}`); } // 解析响应体 const responseBody = response.data; // console.log('API响应体:', responseBody); // 处理不同的API响应结构 let data = []; if (Array.isArray(responseBody)) { // 情况1: 直接返回数组 data = responseBody; } else if (responseBody.data && Array.isArray(responseBody.data)) { // 情况2: { data: [...] } data = responseBody.data; } else if (responseBody.rows && Array.isArray(responseBody.rows)) { // 情况3: { rows: [...] } data = responseBody.rows; } else if (responseBody.result && Array.isArray(responseBody.result)) { // 情况4: { result: [...] } data = responseBody.result; } else { console.error('无法识别的API响应格式:', responseBody); throw new Error('无效的API响应格式'); } // 转换数据格式 bdrOptions.value = data.map(item => { // 调试输出每个项目 // console.log('被测评人原始项:', item); // 尝试可能的字段组合 return { label: item.dcName || item.name || item.username || item.nickname || '未知名称', value: item.dcId || item.id || item.userId || item.value || null }; }); // console.log('转换后的被测评人选项:', bdrOptions.value); // 初始化过滤后的选项 filteredBdrOptions.value = [...bdrOptions.value]; } catch (error) { console.error('获取被测评人失败:', error); // 更详细的错误处理 let errorMsg = '获取被测评人失败'; if (error.errMsg) { if (error.errMsg.includes('401')) { errorMsg = '认证失败,请重新登录'; uni.redirectTo({ url: '/pages/login/login' }); } else if (error.errMsg.includes('timeout')) { errorMsg = '请求超时,请检查网络并重新登录'; uni.redirectTo({ url: '/pages/login/login' }); } else if (error.errMsg.includes('404')) { errorMsg = 'API地址已过期,请重新登录'; uni.redirectTo({ url: '/pages/login/login' }); } else if (error.errMsg.includes('fail')) { errorMsg = `网络请求失败: ${error.errMsg},请联系管理员`; } } else if (error.message) { errorMsg = error.message; } uni.showToast({ title: errorMsg, icon: 'none', duration: 3000 }); } finally { // 添加加载状态管理 bdrLoading.value = false; } }; // 搜索按钮处理 const handleSearch = () => { pagination.current = 1; fetchSurveyData(); }; // 重置按钮处理 const handleReset = () => { formData.dcWjTitle = ''; formData.dcId = []; formData.dcDept = ''; formData.state = null; bdrSearchKeyword.value = ''; showBdrList.value = false; showStateList.value = false; showBdrPlaceholder.value = true; handleSearch(); }; // 编辑/查看问卷 const handleView = (item) => { uni.navigateTo({ url: `/pages/workbench/mycp/operation/operation?id=${item.dcWjId}` }); }; // 分页大小改变 const handleSizeChange = (e) => { pagination.size = e.detail.value; pagination.current = 1; fetchSurveyData(); }; // 页码改变 const handlePageChange = (page) => { pagination.current = page; fetchSurveyData(); }; // 刷新数据 const refreshData = () => { pagination.current = 1; fetchSurveyData(); }; // 页面显示时加载数据 onShow(() => { fetchSurveyData(); fetchBdrList(); }); </script> <template> <view class="container"> <!-- 搜索表单区域 --> <view class="search-card"> <view class="form-group title-group"> <text class="form-label">问卷标题:</text> <input v-model="formData.dcWjTitle" placeholder="请输入问卷标题" class="form-input title-input" /> </view> <view class="form-row"> <!-- 被测评人选择器 --> <view class="form-group form-group-half"> <text class="form-label">被测评人:</text> <view class="search-select-container"> <view class="input-container" @click="showBdrList = true"> <!-- 已选项显示 --> <view v-if="formData.dcId.length > 0" class="selected-display"> {{ selectedBdrLabel }} <view class="delete-icon" @click.stop="handleClearBdr"> <text class="x-icon">&times;</text> </view> </view> <!-- 占位符 --> <text v-else-if="showBdrPlaceholder" class="placeholder-text"> 请选择被测评人 </text> <!-- 下拉箭头 --> <view class="dropdown-icon"> <text>▼</text> </view> </view> <!-- 下拉列表 --> <view v-if="showBdrList" class="dropdown-list"> <view class="search-box"> <input v-model="bdrSearchKeyword" placeholder="搜索被测评人" class="search-input" @input="filterBdrOptions" /> </view> <scroll-view scroll-y="true" class="dropdown-scroll"> <view v-for="(item, index) in filteredBdrOptions" :key="index" class="dropdown-item" :class="{ 'selected': formData.dcId[0] === item.value }" @click="handleBdrSelect(item)" > {{ item.label }} </view> <view v-if="filteredBdrOptions.length === 0" class="empty-option"> 无匹配结果 </view> </scroll-view> </view> <!-- 遮罩层 --> <view v-if="showBdrList" class="dropdown-mask" @click="showBdrList = false" ></view> </view> </view> <!-- 人员部门 --> <view class="form-group form-group-half"> <text class="form-label">人员部门:</text> <input v-model="formData.dcDept" placeholder="请输入部门" class="form-input" /> </view> </view> <!-- 提交状态和按钮组 --> <view class="form-row-bottom"> <!-- 提交状态 --> <view class="state-group"> <text class="form-label">提交状态:</text> <view class="search-select-container"> <view class="state-select-box" @click="toggleStateList"> <text class="selected-state"> {{ getStateLabel(formData.state) }} </text> <view class="dropdown-icon"> <text>▼</text> </view> </view> <!-- 状态下拉列表 --> <view v-if="showStateList" class="dropdown-list state-dropdown"> <view v-for="(state, index) in stateOptions" :key="index" class="dropdown-item" :class="{ 'selected': formData.state === state.value }" @click="handleStateSelect(state)" > {{ state.label }} </view> </view> <!-- 遮罩层 --> <view v-if="showStateList" class="dropdown-mask" @click="showStateList = false" ></view> </view> </view> <!-- 按钮组 --> <view class="button-group"> <button class="search-button" @click="handleSearch">搜索</button> <button class="reset-button" @click="handleReset">重置</button> </view> </view> </view> <!-- 数据显示区域 --> <view class="data-card"> <view class="card-header"> <button class="refresh-button" @click="refreshData">刷新数据</button> </view> <!-- 加载状态 --> <view v-if="loading" class="loading-container"> <view class="loading-spinner"></view> <text class="loading-text">加载中...</text> </view> <!-- 数据展示 --> <view v-else> <view v-for="(item, index) in surveyList" :key="index" class="data-card-item" > <view class="card-header-section"> <view class="card-title">{{ item.dcWjTitle }}</view> </view> <view class="card-body-section"> <view class="card-row"> <text class="card-label">被测评人:</text> <text class="card-value">{{ item.dcName }}</text> </view> <view class="card-row"> <text class="card-label">部门:</text> <text class="card-value">{{ item.dcDept }}</text> </view> <view class="card-row"> <text class="card-label">创建时间:</text> <text class="card-value">{{ item.createTime }}</text> </view> <view class="card-row"> <text class="card-label">提交时间:</text> <text class="card-value">{{ item.updateTime || '-' }}</text> </view> </view> <view class="card-footer-section"> <view class="status-container"> <view :class="[ 'status-tag', item.state === '1' ? 'status-submitted' : 'status-not-submitted' ]" > {{ item.state === '1' ? '已提交' : '未提交' }} </view> <view class="score">总分: {{ item.score || '0' }}</view> </view> <button class="view-button" @click="handleView(item)">编辑/查看</button> </view> </view> <!-- 空数据提示 --> <view v-if="surveyList.length === 0" class="empty"> <text>暂无数据</text> </view> </view> <!-- 分页控件 --> <view v-if="surveyList.length > 0" class="pagination-container"> <picker mode="selector" :range="[5, 10, 20, 50]" :value="[5, 10, 20, 50].indexOf(pagination.size)" @change="handleSizeChange" class="page-size-picker" > <view class="picker"> 每页 {{ pagination.size }} 条 </view> </picker> <view class="pagination-buttons"> <button :disabled="pagination.current === 1" @click="handlePageChange(pagination.current - 1)" class="page-button prev-button" > 上一页 </button> <text class="page-info"> 第 {{ pagination.current }} 页 / 共 {{ Math.ceil(pagination.total / pagination.size) }} 页 </text> <button :disabled="pagination.current >= Math.ceil(pagination.total / pagination.size)" @click="handlePageChange(pagination.current + 1)" class="page-button next-button" > 下一页 </button> </view> <text class="total-records">共 {{ pagination.total }} 条记录</text> </view> </view> </view> </template> 在删除选择的被测评人后,下面的下拉列还是显示的之前搜索出来的名字,我想要删除选择的名字后下拉列表和刚开始加载页面一样直接检索所有的名字,如果名字过多就显示前5个旁边其他的隐藏当往上划动的时候显示出隐藏的名字
最新发布
08-07
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值