请生成新代码 使得webview嵌在页面内可以跟随页面移动 <template>
<view class="wapper">
<!-- <view class="bg-image"></view> -->
<image class="bg-image" src="/static/home/bus/bg-image.png" mode="widthFix" style="width: 100%;" />
<!-- 自定义导航栏 -->
<view class="custom-navbar" :style="{ paddingTop: statusBarHeight + 'px' }">
<view class="navbar-content">
<!-- 左侧返回按钮 -->
<view class="back-btn" @click="handleBack">
<image src="/static/home/bus/back-icon.png" mode="aspectFit" style="width: 48rpx;height: 48rpx;" />
</view>
<!-- 中间标题 -->
<text class="title">{{busLineBase.name}}</text>
</view>
</view>
<view class="wapper-content" :style="{ paddingTop: statusBarHeight +50 + 'px' }">
<view class="line_info">
<view class="site">
<text class="from">{{busLineBase.startSn}}</text>
<view class="arrow">
<text class="to">{{busLineBase.endSn}}</text>
</view>
</view>
<view class="tit">
<view class="time_s">
<text class="time-text">{{busLineBase.firstTime}}</text>
</view>
<view class="time_e">
<text class="time-text">{{busLineBase.lastTime}}</text>
</view>
<text class="price">票价: {{busLineBase.price}}</text>
</view>
</view>
<view class="distance-class">
<view class="station">
<view class="station-title">
<view class="station-name">候车站</view>
<view class="station-content">
<view class="active">{{stationName}}</view>
<view class="underline"></view>
</view>
</view>
</view>
<view class="distance" v-if="state==0 && travelOrder!=0">
<view class="time">
<text class="time_title">{{Math.ceil(travelTime/60)}}分钟</text>
</view>
<text class="arr">{{travelOrder}}站/
<text v-if="travelDistance<1000">{{numFilter(travelDistance)}}m</text>
<text v-else>{{numFilter(travelDistance/1000)}}km</text>
</text>
</view>
<view class="distance" v-else-if="state==0 && travelOrder==0 && isArrive==1">
<view class="time">
<view class="bus-arr">已到站</view>
</view>
</view>
<view class="distance" v-else-if="state==0 &&isArrive==0">
<view class="time">
<view class="bus-coming">即将到站 {{travelDistance}}m</view>
</view>
</view>
<view class="distance" v-else-if="state==-1">
<view class="time">
<view class="none">等待发车</view>
</view>
</view>
<view class="distance" v-else>
<view class="time">
<view class="none">暂无车辆信息</view>
</view>
</view>
<!-- <view>已到站</view> -->
</view>
</view>
<view class="site_list">
<view>
<scroll-view class="wapper_sitelist" scroll-x="true" scroll-with-animation :scroll-into-view="targetId">
<view class="road">
<view class='part' v-for="(item, index) in siteList" @click="showActive(index, item.sn)">
<view :id="'id'+item.sid" class='name'>
<view>
<view class="dot_p" :class="{'dot_p_show': ind === index}"></view>
<view class='dot_r' v-if="index!=siteList.length-1"></view>
</view>
<div :class="item.state==1?'road-bus':'road-bus-coming'" v-if="item.isHaveBus==0"></div>
<view class='dot_d' :class="{'dot_d_show': ind === index}"></view>
<view class='text' :class="{'text_show': ind === index}">
<view>{{index +1}}</view>
<view class="text-dir">
{{item.sn}}
</view>
</view>
</view>
</view>
</view>
</scroll-view>
<!-- <view>
<web-view ref="webview" :webview-styles="webviewStyles" :src="src"
:fullscreen="false"></web-view>
</view> -->
<!-- <view class="page-body">
<view class="page-section page-section-gap">
<map style="width: 100%; height: 250px;" :latitude="latitude" :longitude="longitude"
:markers="covers">
</map>
</view>
</view> -->
</view>
</view>
<view>
<web-view ref="webview" :webview-styles="webviewStyles" :src="src"
:fullscreen="false"></web-view>
</view>
<!-- <iframe ref="iframe" id="iframe" src="./static/map.html" width="100%" height="300px" frameborder="0"
class="map"> -->
</iframe>
</view>
</template>
<script>
import {
getRealTimeBusLine,
getRealTimeBusLineStation
} from '@/request/bus.js'
export default {
data() {
return {
src: './static/web/map.html',
timer: null,
isArrive: 0,
targetId: '',
state: 0,
stationName: '',
travelDistance: 0,
travelTime: 0,
travelOrder: 0,
ratio: '',
ind: '',
siteId: "",
lineName: "二号线",
siteName: "动漫园站",
siteList: [],
busLineBase: [],
stateBus: [],
time_s: '',
time_e: '',
from: '',
busPosition: [0, 5, 11],
to: '',
isActive: false,
lineId: '',
siteNum: '0',
haveBus: true,
webviewStyles: {
position: 'relative',
top: '580px',
// bottom: '30px',
zindex: '9999',
// marginTop: '850px',
left: '20px',
right: '20px',
// height:'300px'
// height: '500px',
},
id: 0, // 使用 marker点击事件 需要填写id
title: 'map',
latitude: 39.90923,
longitude: 116.397428,
covers: [{
latitude: 39.909,
longitude: 116.39742,
iconPath: '../../../static/location.png'
}, {
latitude: 39.90,
longitude: 116.39,
iconPath: '../../../static/location.png'
}]
}
},
onLoad(options) {
// 获取路由参数
const {
statusBarHeight
} = uni.getSystemInfoSync()
// const systemInfo = uni.getSystemInfoSync();
// this.ratio = (systemInfo.windowWidth / 750) / 0.5
console.log("options", options)
this.statusBarHeight = statusBarHeight
this.lineId = options.lineId
this.lat = options.lat
this.lng = options.lng
this.lineName = options.lineName
this.getLineDetail()
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
}
// this.timer = setInterval(() => {
// console.log("30")
// this.refresh()
// }, 1000 * 30);
// this.$nextTick(function() {
// 仅 App 平台执行
// amap.initMap('amap', 'cd0bbe150380e1263de209abf425745b');
this.init()
// })
},
methods: {
// vue向iframe传递信息
init() {
this.src = "../../../../hybrid/html/map.html"
// var res = {
// lineName:this.lineName
// }
// this.src = './static/map.html?data=' + encodeURIComponent(JSON.stringify({
// ...res
// }))
// var lineName = this.lineName
// const iframeWindow = this.$refs.iframe.contentWindow;
// this.dom = document.getElementById('iframe')
// iframeWindow.postMessage({
// cmd: 'myVue',
// params: {
// info: 'Vue向iframe传递的消息',
// }
// }, '*')
},
numFilter(value) {
if (value != 0) {
// 将数值转换为浮点数,并保留两位小数
let realVal = parseFloat(value).toFixed(2);
return realVal;
}
},
async getLineDetail() {
var res = await getRealTimeBusLine({
lineId: this.lineId,
lat: this.lat,
lng: this.lng
})
if (res.code == 0) {
console.log("1", res)
this.siteList = res.data.busInfStop
var ind = res.data.targetOrder
this.ind = res.data.targetOrder - 1
this.stationName = this.siteList[ind - 1].sn
this.state = res.data.state
this.busLineBase = res.data.busLineBase
this.targetOrder = res.data.targetOrder
this.$nextTick(function() {
this.targetId = 'id' + this.siteList[ind - 4].sid
});
if (this.state == 0) {
this.stateBus = res.data.stateBus
var travelsList = this.stateBus.travels
this.distance = this.findAllClosest(this.stateBus, this.targetOrder)
if (this.distance.length != 0) {
var travels = this.distance[0].travels
this.travelDistance = travels[0].travelDistance
this.travelOrder = travels[0].travelOrder
this.travelTime = travels[0].travelTime
this.siteList = this.processArrays(this.siteList, this.stateBus,
'order', 'state');
}
}
}
},
async showActive(index, siteName) {
this.ind = index
this.stationName = siteName
var res = await getRealTimeBusLineStation({
lineId: this.lineId,
stationName: this.stationName
})
if (res.code == 0) {
this.siteList = res.data.busInfStop
var ind = res.data.targetOrder
this.stationName = this.siteList[ind - 1].sn
this.state = res.data.state
this.busLineBase = res.data.busLineBase
this.ind = res.data.targetOrder - 1
this.targetOrder = res.data.targetOrder
this.$nextTick(function() {
this.targetId = 'id' + this.siteList[ind - 4].sid
});
if (this.state == 0) {
this.stateBus = res.data.stateBus
var travelsList = this.stateBus.travels
this.distance = this.findAllClosest(this.stateBus, this.targetOrder)
if (this.distance.length != 0) {
var travels = this.distance[0].travels
this.travelDistance = travels[0].travelDistance
this.travelOrder = travels[0].travelOrder
this.travelTime = travels[0].travelTime
this.isArrive = this.distance[0].state
this.siteList = this.processArrays(this.siteList, this.stateBus,
'order', 'state');
}
}
}
},
handleBack() {
uni.navigateBack()
},
async refresh() {
console.log("刷新")
var res = await getRealTimeBusLineStation({
lineId: this.lineId,
stationName: this.stationName
})
if (res.code == 0) {
this.siteList = res.data.busInfStop
var ind = res.data.targetOrder
this.stationName = this.siteList[ind - 1].sn
this.state = res.data.state
this.busLineBase = res.data.busLineBase
this.ind = res.data.targetOrder - 1
this.targetOrder = res.data.targetOrder
this.$nextTick(function() {
this.targetId = 'id' + this.siteList[ind - 4].sid
});
if (this.state == 0) {
this.stateBus = res.data.stateBus
var travelsList = this.stateBus.travels
this.distance = this.findAllClosest(this.stateBus, this
.targetOrder)
if (this.distance.length != 0) {
var travels = this.distance[0].travels
this.travelDistance = travels[0].travelDistance
this.travelOrder = travels[0].travelOrder
this.travelTime = travels[0].travelTime
this.isArrive = this.distance[0].state
this.siteList = this.processArrays(this.siteList, this
.stateBus, 'order', 'state');
}
}
}
},
// 找到距离最近车站的小车
findAllClosest(arr, target) {
const validItems = arr.filter(item => item.order < target + 1);
if (validItems.length === 0) return [];
const distances = validItems.map(item => ({
item,
distance: Math.abs(item.order - target)
}));
if (distances.length != 0) {
const minDist = Math.min(...distances.map(d => d.distance));
return distances.filter(d => d.distance === minDist).map(d => d.item);
}
},
processArrays(arrayA, arrayB, key, valueKey) {
// 创建arrayB的快速查找映射(基于指定键)
const bMap = new Map();
arrayB.forEach(item => {
if (item[key] !== undefined) {
bMap.set(item[key], item);
}
});
// 遍历arrayA并添加属性
return arrayA.map(itemA => {
// 浅拷贝避免修改原对象
const newItem = {
...itemA
};
// 检查是否存在匹配元素
if (bMap.has(newItem[key])) {
const matchedB = bMap.get(newItem[key]);
// newItem.state = 0;
newItem.isHaveBus = 0;
// 添加arrayB中的属性值(如果存在)
if (matchedB[valueKey] !== undefined) {
newItem[valueKey] = matchedB[valueKey];
}
}
return newItem;
});
}
},
onPullDownRefresh() {
console.log("下拉")
this.refresh()
setTimeout(() => {
//结束下拉刷新
uni.stopPullDownRefresh();
}, 1000);
},
onUnload() {
console.log('页面即将卸载');
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
}
},
}
</script>
<style>
page {
background-color: #f5f5f5;
}
</style>
<style scoped>
.bg-image {
position: absolute;
}
.custom-navbar {
position: absolute;
top: 0;
left: 0;
width: 100%;
z-index: 1000;
/* 自定义背景色 */
/* 自定义阴影 */
}
.navbar-content {
height: 44px;
/* 标准导航栏高度 */
display: flex;
align-items: center;
padding: 0 15px;
}
.title {
flex: 1;
text-align: center;
font-size: 17px;
font-weight: bold;
color: #333;
/* 标题颜色 */
}
.back-btn {
width: 48rpx;
height: 48rpx;
}
.right-area {
width: 40px;
text-align: right;
}
.info_wapper {
height: 156px;
/* background: #36A3F9; */
/* background: url(@/static/home/bus/detail-bg.png) left no-repeat; */
padding: 15px;
color: black;
position: absolute;
z-index: 9;
width: 100%;
}
.line_info {
position: relative;
/* display: flex; */
}
.site {
font-size: 32rpx;
color: black;
margin-bottom: 10px;
text-align: left;
display: flex;
margin-left: 30px;
}
.from {
/* padding-left: 52rpx; */
color: black;
}
.arrow {
background: url(@/static/home/bus/single.png) left no-repeat;
background-size: 14px 5px;
margin-left: 10px;
color: black;
}
.to {
padding-left: 26px;
color: black;
}
.time_s {
background: url(@/static/home/bus/start.png) left no-repeat;
background-size: 18px 18px;
justify-self: baseline;
}
.time_e {
background: url(@/static/home/bus/end.png) left no-repeat;
background-size: 18px 18px;
margin-left: 15px;
}
.price {
margin-left: 15px;
}
.tit {
color: #fff;
font-size: 26rpx;
/* padding-left: 52rpx; */
margin-bottom: 10px;
height: 21px;
color: #333;
display: flex;
align-items: baseline;
margin-left: 30px;
}
.distance-class {
border-radius: 15px;
/* box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1); */
background: url(@/static/home/bus/distance-bg.png) center no-repeat;
background-size: cover;
height: 150px;
position: absolute;
z-index: 9999;
left: 20px;
right: 20px;
}
.distance {
color: #B7BABB;
line-height: 20px;
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
position: relative;
z-index: 9999;
/* align-items: baseline; */
}
.time {
color: aquamarine;
}
.bus-arr {
color: rgb(255, 164, 17);
font-weight: bold;
margin-top: 10px;
}
.bus-coming {
color: rgb(55, 170, 126);
font-weight: bold;
line-height: 100rpx;
}
.station {
margin-left: 20px;
color: #353738;
padding: 10px;
}
.station-title {
display: flex;
align-items: baseline;
}
.station-name {
margin-right: 15px;
}
.station-content {
padding-top: 10px;
/* padding-left: 20rpx; */
position: relative;
/* padding-right: 50rpx; */
/* 确保文字在下划线上方 */
z-index: 2;
justify-content: center;
display: flex;
align-items: center;
/* 文字在上层 */
}
.underline {
position: absolute;
bottom: 2px;
height: 3px;
background: linear-gradient(to right, rgb(110, 207, 169), rgb(110, 224, 176));
/* 下划线颜色 */
border-radius: 3px;
z-index: -1;
width: 80%;
align-items: center;
justify-content: center;
display: flex;
/* margin-left: 30rpx; */
/* width: 60rpx; */
/* 下划线在文字下方 */
}
.active {
color: black;
/* 激活状态文字颜色 */
font-weight: bold;
/* font-size: 36rpx; */
}
.time {
float: left;
width: 40%;
font-size: 26rpx;
/* height: 130rpx; */
line-height: 30px;
}
.time {
font-size: 36rpx;
color: #353738;
}
.time-text {
margin-left: 25px;
}
.time_title {
color: rgb(14, 170, 112);
font-weight: bold;
}
.arr {
float: left;
/* width: 20%; */
font-size: 30rpx;
color: rgb(14, 170, 112);
}
.site_list {
/* margin: 15px; */
/* box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1); */
/* background-color: white; */
border-radius: 15px;
margin-top: 140px;
padding-left: 15px;
padding-right: 15px;
padding-top: 15px;
padding-bottom: 10px;
background: url(@/static/home/bus/site-bg.png) center no-repeat;
position: absolute;
z-index: 9999;
left: 20px;
right: 20px;
background-size: cover;
/* 让背景图片覆盖整个视口 */
}
.site_list .wapper_sitelist {
width: 100%;
overflow-x: scroll;
position: relative;
-webkit-overflow-scrolling: touch;
display: flex;
/* margin-bottom: 200px; */
}
.bus_road {
background: url(@/static/home/bus/bus.png) no-repeat center;
background-size: cover;
width: 28px;
height: 14px;
position: absolute;
z-index: 1;
margin-top: 4px;
left: 14px;
/* margin-top: -40px; */
}
.road-bus {
background: url(@/static/home/bus/bus.png) no-repeat center;
background-size: cover;
width: 28px;
height: 14px;
position: absolute;
z-index: 1;
margin-top: -45px;
margin-left: 10px;
/* left: 14px; */
/* margin-top: -40px; */
}
.road-bus-coming {
background: url(@/static/home/bus/bus.png) no-repeat center;
background-size: cover;
width: 28px;
height: 14px;
position: absolute;
z-index: 1;
margin-top: -45px;
margin-left: -40px;
}
.road {
display: flex;
}
.wapper_sitelist::-webkit-scrollbar {
display: none;
}
/deep/::-webkit-scrollbar {
display: none;
width: 0;
height: 0;
}
.part {
padding: 10px;
display: flex;
flex-direction: row;
text-align: center;
justify-content: center;
padding-top: 20px;
}
.site_list .dot_r {
margin-top: 10px;
position: absolute;
top: 23px;
height: 3px;
background: linear-gradient(to right, rgb(110, 207, 169), rgb(110, 224, 176));
/* 下划线颜色 */
width: 46px;
border-radius: 3rpx;
z-index: 1;
margin-left: 4px;
align-items: center;
justify-content: center;
display: flex;
}
.site_list .name {
margin-top: 28px;
display: flex;
flex-direction: column;
align-items: center;
}
.site_list .text {
display: flex;
text-align: center;
margin-left: 5px;
flex-direction: column;
}
.site_list .text_show {
display: flex;
text-align: center;
margin-left: 5px;
color: rgb(14, 170, 112);
font-weight: bold;
}
.site_list .dot_show {
background: url(@/static/home/bus/position_red.png) no-repeat center;
background-size: 14px 18px;
}
.site_list .dot_d_show {
border-radius: 50%;
width: 16px;
height: 16px;
background-color: rgba(110, 207, 169, 0.5);
position: absolute;
z-index: 9999;
top: 26px;
margin-left: 8px;
display: flex;
align-items: center;
justify-content: center;
}
.road-class {
display: flex;
}
.dot_p {
border-radius: 50%;
width: 8px;
height: 8px;
background-color: rgb(110, 207, 169);
position: absolute;
z-index: 9999;
top: 30px;
display: flex;
align-items: center;
justify-content: center;
/* margin-right: 2px; */
/* margin-left: 10rpx; */
}
.dot_p_show {
border-radius: 50%;
width: 8px;
height: 8px;
background-color: rgb(14, 170, 112);
position: absolute;
z-index: 9999;
top: 30px;
display: flex;
align-items: center;
justify-content: center;
}
.text-dir {
margin-top: 5px;
writing-mode: vertical-rl;
letter-spacing: 1px;
}
.none {
color: #848484;
font-size: 16px;
margin-top: 15px;
}
.map {
/* margin-top: 450px; */
position: absolute;
z-index: 999;
margin-top: 480px;
/* height: 300px; */
}
.web-class {
/* top: 800px; */
/* height: 300px; */
/* position: absolute;
z-index: 99999; */
width: 100%;
margin-top: 500px;
}
.page-body {
margin-top: 250px;
padding-bottom: 20px;
}
</style>
最新发布