时间选择器滑动选择日期的时候总会触发主页面背景滑动,特别是拉到顶部或者底部的时候,主页面背景抖动非常严重,百度了很多资料,试了好几种方法,都没能解决这个问题,哪位踩过坑的大神可以提供一下思路。。。。
这是时间选择器组件的核心代码:
<template>
<div>
<div class="picker_content">
<div class="picker_title">
<span class="title_cancel" @click="cancelChooseDate">取消</span>
<span class="title_text">请选择{{data}}时间</span>
<span class="title_submit" @click="submitChooseDate">确定</span>
</div>
<div class="picker_body">
<div class="center_body"></div>
<div class="body_year" @scroll.prevent="scrollDate('year')">
<div class="year_body" v-for="(item, index) in yearData" :key="index">
<span class="year_text">{{item}}</span>
</div>
</div>
<div class="body_month" @scroll.prevent="scrollDate('month')">
<div class="month_body" v-for="(item, index) in monthData" :key="index">
<span class="month_text">{{item}}</span>
</div>
</div>
<div class="body_day" @scroll.prevent="scrollDate('day')">
<div class="day_body" v-for="(item, index) in dayData" :key="index">
<span class="day_text">{{item}}</span>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
data: {
type: String,
default: ''
},
theDate: {
type: String,
default: ''
}
},
data() {
return {
initData: ['1', '2', '3', '4', '5'],
yearData: ['', '', '2018年', '2019年', '2020年', '2021年', '2022年', '', ''],
monthData: ['', '', '1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月' ,'11月', '12月', '', ''],
allDayData: ['', '', '1号', '2号', '3号', '4号', '5号', '6号', '7号', '8号', '9号', '10号', '11号', '12号', '13号', '14号', '15号', '16号', '17号', '18号', '19号', '20号', '21号', '22号', '23号', '24号', '25号', '26号', '27号', '28号', '29号', '30号', '31号', '', ''],
dayData: [],
year: undefined,
month: undefined,
day: undefined,
temp: {
selectedMonth: undefined,
selectedDay: undefined,
beginOrEnd: undefined
}
}
},
created() {
this.dayData = this.allDayData
},
watch: {
theDate: 'initDate'
},
methods: {
initDate() {
let _date = new Date()
let _year = _date.getFullYear() + '年'
let _month = this.theDate.split('月')[0] + '月'
let _day = this.theDate.split('月')[1]
//定位当前年份并高亮
for (const v of this.yearData) {
if (_year == v) {
document.getElementsByClassName('body_year')[0].scrollTop = (this.yearData.indexOf(v) - 2) * 42
document.getElementsByClassName('body_year')[0].children[this.yearData.indexOf(v)].children[0].classList.add('selected_style')
}
}
//定位当前月份并高亮
for (const v of this.monthData) {
if (_month == v) {
document.getElementsByClassName('body_month')[0].scrollTop = (this.monthData.indexOf(v) - 2) * 42
document.getElementsByClassName('body_month')[0].children[this.monthData.indexOf(v)].children[0].classList.add('selected_style')
}
}
//定位当前天数并高亮
for (const v of this.dayData) {
if (_day == v) {
document.getElementsByClassName('body_day')[0].scrollTop = (this.dayData.indexOf(v) - 2) * 42
document.getElementsByClassName('body_day')[0].children[this.dayData.indexOf(v)].children[0].classList.add('selected_style')
}
}
},
scrollDate(data) {
let _yearArr = []
let _monthArr = []
let _dayArr = []
for (const v of document.getElementsByClassName('body_year')[0].children) {
_yearArr.push(v)
}
for (const v of document.getElementsByClassName('body_month')[0].children) {
_monthArr.push(v)
}
for (const v of document.getElementsByClassName('body_day')[0].children) {
_dayArr.push(v)
}
if (data == 'year') {
let a = document.getElementsByClassName('body_year')[0].scrollTop
let year = undefined
let month = undefined
//取当前高亮月份
for (const v of _monthArr) {
if (v.children[0].classList[1] == 'selected_style') {
month = parseInt(v.children[0].innerText.slice(0, -1))
}
}
for (const v of _yearArr) {
if (((2 + parseInt(a/42)) == _yearArr.indexOf(v)) && (a%42 <= 21)) {
v.children[0].classList.add('selected_style')
//取当前高亮年份
year = parseInt(v.children[0].innerText.slice(0, -1))
//根据当前月份判断天数
if (month == '1' || month == '3' || month == '5' || month == '7' || month == '8' || month == '10' || month == '12') {
this.dayData = this.allDayData
}
if (month == '4' || month == '6' || month == '9' || month == '11') {
this.dayData = this.allDayData.slice(0, -3)
this.dayData.push('')
this.dayData.push('')
}
//当前月份为二月份时联合当前年份判断天数
if (month == '2' && year%4 == 0) {
this.dayData = this.allDayData.slice(0, -4)
this.dayData.push('')
this.dayData.push('')
}
if (month == '2' && year%4 != 0) {
this.dayData = this.allDayData.slice(0, -5)
this.dayData.push('')
this.dayData.push('')
}
} else {
v.children[0].classList.remove('selected_style')
}
}
}
if (data == 'month') {
let a = document.getElementsByClassName('body_month')[0].scrollTop
let year = undefined
//取当前高亮年份
for (const v of _yearArr) {
if (v.children[0].classList[1] == 'selected_style') {
year = parseInt(v.children[0].innerText.slice(0, -1))
}
for (const v of _monthArr) {
if (((2 + parseInt(a/42)) == _monthArr.indexOf(v)) && (a%42 <= 21)) {
v.children[0].classList.add('selected_style')
//取当前高亮月份
let month = parseInt(v.children[0].innerText.slice(0, -1))
//判断该月份确定天数
if (month == '1' || month == '3' || month == '5' || month == '7' || month == '8' || month == '10' || month == '12') {
this.dayData = this.allDayData
}
if (month == '4' || month == '6' || month == '9' || month == '11') {
this.dayData = this.allDayData.slice(0, -3)
this.dayData.push('')
this.dayData.push('')
}
//当前月份为二月份时联合当前年份判断天数
if (month == '2' && year%4 == 0) {
this.dayData = this.allDayData.slice(0, -4)
this.dayData.push('')
this.dayData.push('')
}
if (month == '2' && year%4 != 0) {
this.dayData = this.allDayData.slice(0, -5)
this.dayData.push('')
this.dayData.push('')
}
} else {
v.children[0].classList.remove('selected_style')
}
}
}
}
if (data == 'day') {
let a = document.getElementsByClassName('body_day')[0].scrollTop
for (const v of _dayArr) {
if (((2 + parseInt(a/42)) == _dayArr.indexOf(v)) && (a%42 <= 21)) {
v.children[0].classList.add('selected_style')
} else {
v.children[0].classList.remove('selected_style')
}
}
}
},
cancelChooseDate() {
this.$emit('closeTimePicker', false)
},
submitChooseDate() {
let _monthArr = []
let _dayArr = []
for (const v of document.getElementsByClassName('body_month')[0].children) {
_monthArr.push(v)
}
for (const v of document.getElementsByClassName('body_day')[0].children) {
_dayArr.push(v)
}
for (const v of _monthArr) {
if (v.children[0].classList[1] == 'selected_style') {
this.temp.selectedMonth = v.children[0].innerText
}
}
for (const v of _dayArr) {
if (v.children[0].classList[1] == 'selected_style') {
this.temp.selectedDay = v.children[0].innerText
}
}
this.temp.beginOrEnd = this.data
this.$emit('chooseDate', this.temp)
}
}
}
</script>
这是首页的代码:
<template>
<div class="container">
<div class="bgColor" style="height:100%;width:100%;background-color: #f5f5f5;">
<Swiper v-if="list.length > 0" :autoPlay='true' :showIndicator='true' interval="2500" duration="500">
<Slide v-for="(item,index) in list" :key="index">
<img class="img" :src=item.src>
</Slide>
</Swiper>
<div class="body_top">
<div class="freedomCoach" @click="selectedFreedom">
<span class="freedomCoachText">查找教练</span>
</div>
<div class="myCoach" @click="selectedMy">
<span class="myCoachText">我的教练</span>
</div>
</div>
<div class="body_outside">
<div class="body">
<div class="body_left">
<img class="left_image" src="../assets/IndexDemo/weizhi@2x.png">
</div>
<div class="body_right">
<span class="right_city">{{nowCity}}</span>
<div class="right_location" @click="refresh">
<img class="right_location_image" src="../assets/IndexDemo/shape@2x.png">
<span class="right_location_text" id="myLocation">我的位置</span>
</div>
</div>
</div>
<div class="body">
<div class="body_left">
<img class="left_image" src="../assets/IndexDemo/booking_cat@2x.png">
</div>
<div class="body_right">
<div class="gear_project" v-for="(item1, index1) in gearData" :key="index1" @click="chooseGearType(index1)">
<div class="project_point"></div>
<span class="project_text">{{item1}}</span>
</div>
</div>
</div>
<div class="body">
<div class="body_left">
<img class="left_image" src="../assets/IndexDemo/shijian@2x.png">
</div>
<div class="body_right">
<div class="right_beginDate" @click="chooseBeginDate">
<span class="begin_text">开始</span>
<span class="begin_date">{{beginDate}}</span>
</div>
<img class="right_centerImg" src="../assets/IndexDemo/next@2x.png">
<div class="right_endDate" @click="chooseEndDate">
<span class="end_text">结束</span>
<span class="end_date">{{endDate}}</span>
</div>
</div>
</div>
<div class="body">
<div class="body_left">
<img class="left_image" src="../assets/IndexDemo/xiangmu@2x.png">
</div>
<div class="body_right">
<div class="right_project" v-for="(item, index) in indexData" :key="index" @click="chooseOnePrj(index)">
<div class="project_point"></div>
<span class="project_text">{{item}}</span>
</div>
</div>
</div>
<div class="body">
<div class="body_left">
<img class="left_image" src="../assets/IndexDemo/sousuo@2x.png">
</div>
<div class="body_right">
<input class="right_input" v-model="searchString" placeholder="搜索教练、驾校等等">
</div>
</div>
<div class="body_appointment" @click="searchCoach">
<span class="appointment_text">开始搜索</span>
</div>
</div>
<img class="adImage" src="../assets/IndexDemo/home_banner_03@2x.png" @click="toCoachesList">
<FooterItem></FooterItem>
</div>
<!-- 时间选择器引用 -->
<time-picker :titleData="titleData" :theDate="theDate" :showSomething="showTimePicker" @returnData="returnData" @returnStatus="returnStatus"></time-picker>
<!-- 提示框组件引用 -->
<toast :showSomething="showToast" :title="toastTitle" :width="toastWidth" :type="toastType" @changeShow="changeShow"></toast>
<!-- Loading组件引用 -->
<loading :showSomething="showLoading"></loading>
</div>
</template>
<script>
import { Swiper, Slide } from "vue-swiper-component";
import FooterItem from "../components/Footer/Footer";
import TimePicker from "../components/TimePicker/Index";
import Toast from "../components/Toast/Index";
import constants from "../utils/constants";
import { isNullOrEmpty } from "../utils/validate";
import { getAdImage } from "../api/Index/index";
import Loading from "../components/Loading/Index";
export default {
data() {
return {
indexData: ["报名学车", "科目二", "科目三"],
showTimePicker: false,
titleData: undefined,
beginDate: "",
endDate: "",
theDate: "",
nowCity: "",
subjectType: undefined,
searchString: "",
showToast: undefined,
toastTitle: "",
toastWidth: "",
toastType: "",
showLoading: undefined,
list: [],
indexDetails: {},
address: "",
tempCity: "",
adcode: "",
gearData: ["C1手动", "C2自动"],
gearType: undefined
};
},
components: {
FooterItem,
TimePicker,
Toast,
Swiper,
Slide,
Loading
},
created() {
let vm = this;
let date = new Date();
let _beginDate = date.getFullYear();
let _endDate = date.getFullYear();
if (date.getMonth() + 1 < 10) {
_beginDate = _beginDate + "-" + "0" + (date.getMonth() + 1);
_endDate = _endDate + "-" + "0" + (date.getMonth() + 1);
} else {
_beginDate = _beginDate + "-" + (date.getMonth() + 1);
_endDate = _endDate + "-" + "0" + (date.getMonth() + 1);
}
if (date.getDate() < 10) {
_beginDate = _beginDate + "-" + "0" + date.getDate();
// _endDate = _endDate + "-" + "0" + date.getDate();//默认结束时间与开始时间为同一天
_endDate = _endDate + "-" + "0" + (date.getDate() + 6); //默认结束时间与开始时间间隔一周
} else {
_beginDate = _beginDate + "-" + date.getDate();
// _endDate = _endDate + "-" + date.getDate();//默认结束时间与开始时间为同一天
_endDate = _endDate + "-" + (date.getDate() + 6); //默认结束时间与开始时间间隔一周
}
window.localStorage.setItem(constants.startDate, _beginDate);
window.localStorage.setItem(constants.endDate, _endDate);
vm.beginDate = date.getMonth() + 1 + "月" + date.getDate() + "号";
// vm.endDate = date.getMonth() + 1 + "月" + date.getDate() + "号";//默认结束时间与开始时间为同一天
// vm.endDate = date.getMonth() + 1 + "月" + (date.getDate() + 6) + "号";//默认结束时间与开始时间间隔一周
let dayTime = date.setDate(date.getDate() + 6); //获取当前时间+6天的时间戳
let d = new Date(dayTime);
let M =
(date.getMonth()[0] + 1 < 10
? "0" + (date.getMonth() + 1)
: date.getMonth() + 1) + "月";
let D = date.getDate() + "号";
vm.endDate = M + D;
var map, geolocation, searchcity, geocoder;
map = new AMap.Map("container", {
resizeEnable: true
});
//加载地图,调用城市查询服务
map.plugin("AMap.CitySearch", function() {
searchcity = new AMap.CitySearch({
enableHighAccuracy: true //是否使用高精度定位,默认:true
});
map.addControl(searchcity);
searchcity.getLocalCity();
AMap.event.addListener(searchcity, "complete", onSearchComplete); //返回城市信息
});
function onSearchComplete(data) {
vm.nowCity = data.city;
}
//加载地图,调用浏览器定位服务
map.plugin("AMap.Geolocation", function() {
geolocation = new AMap.Geolocation({
enableHighAccuracy: true, //是否使用高精度定位,默认:true
timeout: 10000 //超过10秒后停止定位,默认:无穷大
});
map.addControl(geolocation);
geolocation.getCurrentPosition();
AMap.event.addListener(geolocation, "complete", onComplete); //返回定位信息
});
function onComplete(data) {
data.position.getLat();
data.position.getLng();
let _lat = data.position.getLat();
let _lng = data.position.getLng();
window.localStorage.setItem(constants.latitude, _lat);
window.localStorage.setItem(constants.longitude, _lng);
//逆地理编码插件引入与对象创建
map.plugin("AMap.Geocoder", function() {
//回调函数
//实例化Geocoder
geocoder = new AMap.Geocoder({
city: "020" //城市,默认:“全国”
});
//逆地理编码
var lnglatXY = [data.position.getLng(), data.position.getLat()];
geocoder.getAddress(lnglatXY, function(status, result) {
if (status === "complete" && result.info === "OK") {
//获得了有效的地址信息:
result.regeocode.formattedAddress;
vm.adcode =
result.regeocode.addressComponent.adcode.slice(0, 4) + "00";
vm.nowCity = result.regeocode.addressComponent.city; //教练列表定位城市
vm.tempCity = result.regeocode.addressComponent.city;
vm.address =
result.regeocode.addressComponent.street +
result.regeocode.addressComponent.streetNumber; //学员当前定位位置
} else {
alert("获取地址失败");
}
});
});
}
// let _lat = "23.133267";
// let _lng = "113.368004";
// window.localStorage.setItem(constants.latitude, _lat);
// window.localStorage.setItem(constants.longitude, _lng);
//首页加载广告轮播图
vm.showLoading = true;
let _imgList = [];
getAdImage().then(response => {
const data = response.data;
vm.indexDetails = data.data;
for (const v of vm.indexDetails) {
let _tmp = {};
_tmp.src = v.imgUrl;
_imgList.push(_tmp);
}
for (const v of _imgList) {
vm.list.push(v);
}
vm.showLoading = false;
});
},
mounted() {
// document.getElementsByClassName("bgColor")[0].style.cssText =
// "position:absolute; left: 0; top: 0; width: 100%; height: " +
// window.screen.height +
// "px; z-index: -1; background-color: #f5f5f5;";
// "position:absolute; left: 0; top: 0; width: 100%; height: 106%; z-index: -1;background-color: #f5f5f5;"
document
.getElementsByClassName("freedomCoach")[0]
.classList.add("selectedStyle");
document
.getElementsByClassName("freedomCoachText")[0]
.classList.add("selectedTextStyle");
},
methods: {
chooseOnePrj(data) {
let _arr = [];
for (const v of document.getElementsByClassName("right_project")) {
_arr.push(v);
}
for (const v of _arr) {
if (data == _arr.indexOf(v)) {
v.children[0].classList.add("choose_point_style");
v.children[1].classList.add("choose_text_style");
if (v.children[1].innerText == "报名学车") {
this.subjectType = " ";
} else if (v.children[1].innerText == "科目二") {
this.subjectType = "1";
} else {
this.subjectType = "2";
}
} else {
v.children[0].classList.remove("choose_point_style");
v.children[1].classList.remove("choose_text_style");
}
}
},
chooseGearType(data) {
let _arr = [];
for (const v of document.getElementsByClassName("gear_project")) {
_arr.push(v);
}
for (const v of _arr) {
if (data == _arr.indexOf(v)) {
v.children[0].classList.add("choose_point_style");
v.children[1].classList.add("choose_text_style");
if (v.children[1].innerText == "C1手动") {
this.gearType = "c1";
} else {
this.gearType = "c2";
}
} else {
v.children[0].classList.remove("choose_point_style");
v.children[1].classList.remove("choose_text_style");
}
}
},
chooseBeginDate() {
this.showTimePicker = true;
this.theDate = this.beginDate;
this.titleData = "开始";
},
chooseEndDate() {
this.showTimePicker = true;
this.theDate = this.endDate;
this.titleData = "结束";
},
returnData(data) {
this.showTimePicker = data.show;
let _date = new Date();
if (data.text == "开始") {
this.beginDate = data.date;
let _beginDate = _date.getFullYear();
if (this.beginDate.split("月")[0] < 10) {
_beginDate = _beginDate + "-" + "0" + this.beginDate.split("月")[0];
} else {
_beginDate = _beginDate + "-" + this.beginDate.split("月")[0];
}
if (this.beginDate.split("月")[1].split("号")[0] < 10) {
_beginDate =
_beginDate +
"-" +
"0" +
this.beginDate.split("月")[1].split("号")[0];
} else {
_beginDate =
_beginDate + "-" + this.beginDate.split("月")[1].split("号")[0];
}
window.localStorage.setItem(constants.startDate, _beginDate);
}
if (data.text == "结束") {
this.endDate = data.date;
let _endDate = _date.getFullYear();
if (this.endDate.split("月")[0] < 10) {
_endDate = _endDate + "-" + "0" + this.endDate.split("月")[0];
} else {
_endDate = _endDate + "-" + this.endDate.split("月")[0];
}
if (this.endDate.split("月")[1].split("号")[0] < 10) {
_endDate =
_endDate + "-" + "0" + this.endDate.split("月")[1].split("号")[0];
} else {
_endDate =
_endDate + "-" + this.endDate.split("月")[1].split("号")[0];
}
window.localStorage.setItem(constants.endDate, _endDate);
}
this.theDate = "";
},
returnStatus(data) {
this.showTimePicker = data;
this.theDate = "";
},
selectedFreedom() {
//清除样式
document
.getElementsByClassName("myCoach")[0]
.classList.remove("selectedStyle");
document
.getElementsByClassName("myCoachText")[0]
.classList.remove("selectedTextStyle");
//增加样式
document
.getElementsByClassName("freedomCoach")[0]
.classList.add("selectedStyle");
document
.getElementsByClassName("freedomCoachText")[0]
.classList.add("selectedTextStyle");
},
selectedMy() {
//清除样式
document
.getElementsByClassName("freedomCoach")[0]
.classList.remove("selectedStyle");
document
.getElementsByClassName("freedomCoachText")[0]
.classList.remove("selectedTextStyle");
//增加样式
document
.getElementsByClassName("myCoach")[0]
.classList.add("selectedStyle");
document
.getElementsByClassName("myCoachText")[0]
.classList.add("selectedTextStyle");
//跳转至团队教练页面
this.$router.push({
path: "/teamCoachesList"
});
},
computingTime(data1, data2) {
let data;
let days;
let date = new Date();
data1 =
date.getFullYear() +
"/" +
data1.split("月")[0] +
"/" +
data1.split("月")[1].split("号")[0];
data2 =
date.getFullYear() +
"/" +
data2.split("月")[0] +
"/" +
data2.split("月")[1].split("号")[0];
data1 = Date.parse(data1);
data2 = Date.parse(data2);
data = data2 - data1;
data = Math.abs(data);
days = Math.floor(data / (24 * 3600 * 1000));
if (days < 7) {
return true;
} else {
return false;
}
},
searchCoach() {
if (isNullOrEmpty(this.subjectType)) {
this.showToast = true;
this.toastTitle = "请选择科目";
this.toastType = "text";
return;
}
if (!this.computingTime(this.endDate, this.beginDate)) {
this.showToast = true;
this.toastTitle = "所选日期应一周内";
this.toastType = "text";
this.toastWidth = "200px";
return;
}
if (isNullOrEmpty(this.gearType)) {
this.showToast = true;
this.toastTitle = "请选择驾照类型";
this.toastType = "text";
return;
}
window.localStorage.setItem(
constants.currentCity,
this.tempCity
// document.getElementsByClassName("right_city")[0].innerText
);
window.localStorage.setItem(constants.subjectTypeId, this.subjectType);
window.localStorage.setItem(constants.gearType, this.gearType);
// window.localStorage.setItem(constants.currentCityCode, "440100");
window.localStorage.setItem(constants.currentCityCode, this.adcode);
if (this.searchString) {
window.localStorage.setItem(constants.searchStr, this.searchString);
} else {
window.localStorage.setItem(constants.searchStr, " ");
}
setTimeout(() => {
this.$router.push({
path: "/coachesList"
});
}, 500);
},
changeShow(data) {
this.showToast = data;
this.toastTitle = "";
this.toastType = "";
this.toastWidth = "";
},
toCoachesList() {
this.subjectType = "2";
window.localStorage.setItem(constants.subjectTypeId, this.subjectType);
this.$router.push({
path: "/coachesList",
query: {
type: "peilian"
}
});
},
refresh() {
this.nowCity = this.address;
document.getElementById("myLocation").style.color = "#0084ff";
}
}
};
</script>
有好几种解决办法,推荐使用背景容器在蒙层出现的时候,高度变成100vh,等到消失的时候成为auto,这种相对来说副作用少一点。还有底部是不是用的是fixed 定位?fixed定位里面的内容,如果用到了滚动,可以使用模拟滚动,尝试一下better-scroll,IScroll,或者Swiper等来模拟出滚动效果。使用原生的滚动就算上下不发生问题,也会产生别的问题。