提交 5e0dca93 authored 作者: 龙菲's avatar 龙菲

完善展览详情页的tabbar滚动联动交互效果

上级 722faeb9
......@@ -101,7 +101,6 @@ export default {
this.$nextTick(() => {
const swiperTop = this.$refs.swiperTop.swiper;
const swiperThumbs = this.$refs.swiperThumbs.swiper;
console.log(this.$refs);
swiperTop.controller.control = swiperThumbs;
swiperThumbs.controller.control = swiperTop;
});
......
......@@ -137,7 +137,7 @@ $themeColor: #2069c4;
height: 100%;
display: flex;
flex-direction: column;
padding-bottom: 60px;
padding-bottom: 10px;
.img-container {
width: 100%;
// height: 100%;
......@@ -165,8 +165,8 @@ $themeColor: #2069c4;
}
.enlarge {
position: absolute;
bottom: 80px;
right: 0px;
bottom: 19px;
right: -7px;
display: flex;
z-index: 9;
display: flex;
......
......@@ -42,7 +42,7 @@ export function getFullUrl(url) {
* @param href 预览地址
* @param previewName 预览文件用户看到的名称
*/
export function previewFile(href, previewName) {
export function previewFile(href, previewName) {
let a = document.createElement("a");
a.href = href;
a.target = '_blank'
......@@ -58,10 +58,10 @@ export function getFullUrl(url) {
* 增加千位分割符
* @param num
*/
export function addSeparator(num){
var res=num.toString().replace(/\d+/, function(n){ // 先提取整数部分
return n.replace(/(\d)(?=(\d{3})+$)/g,function($1){
return $1+",";
export function addSeparator(num) {
var res = num.toString().replace(/\d+/, function (n) { // 先提取整数部分
return n.replace(/(\d)(?=(\d{3})+$)/g, function ($1) {
return $1 + ",";
});
})
return res;
......@@ -83,3 +83,34 @@ export function formatNum(num) {
return (num / 10000).toFixed(1) + 'w';
}
}
// 监听某元素是否在可视区,使用getBoundingClientRect
export const isElementInViewport = function (el) {
// rect.top 元素距离视窗的位置
//window.innerHeight || document.documentElement.clientHeight 文档的高度,前为BOM对象方式获取,后为DOM对象方式获取
if (el) {
const viewWidth =
window.innerWidth || document.documentElement.clientWidth;
const viewHeight =
window.innerHeight || document.documentElement.clientHeight;
const { top, right, bottom, left } = el.getBoundingClientRect();
return (
top >= 0 && left >= 0 && right <= viewWidth && bottom <= viewHeight
);
}
};
// 监听某元素是否在可视区,使用getBoundingClientRect
export const isElementInViewport2 = function (content) {
let scrollTop =
window.pageYOffset ||
document.documentElement.scrollTop ||
document.body.scrollTop;
let clientHeight =
document.documentElement.clientHeight || window.innerHeight;
if (content) {
return (content.offsetTop + content.offsetHeight > scrollTop &&
content.offsetTop < scrollTop + clientHeight)
}
};
......@@ -141,65 +141,69 @@
id="tabbar"
:class="{ isFixed: isFixed }"
>
<span v-for="(item, index) in tabbarData" :key="index">
<span
v-if="displayDetail.intro"
@click="handleClickTabItem('intro')"
:class="['tab-item', currentTab == 'intro' ? 'active' : '']"
>展览简介</span
>
<span
v-if="displayDetail.videosVo && displayDetail.videosVo.length > 0"
@click="handleClickTabItem('videos')"
:class="['tab-item', currentTab == 'videos' ? 'active' : '']"
>展览视频</span
>
<span
v-if="
displayDetail.exhibitionUnits &&
displayDetail.exhibitionUnits.length > 0
"
@click="handleClickTabItem('exhibitionUnits')"
@click="handleClickTabItem(item)"
:class="[
'tab-item',
currentTab == 'exhibitionUnits' ? 'active' : '',
currentTab && currentTab.domId == item.domId ? 'active' : '',
]"
>展览单元</span
>
<span
v-if="relateRelics"
@click="handleClickTabItem('relateRelics')"
:class="['tab-item', currentTab == 'relateRelics' ? 'active' : '']"
>展览文物</span
>
<span
v-html="item.name"
v-if="
displayDetail.literatureVo &&
displayDetail.literatureVo.length > 0
displayDetail[item.domId] &&
displayDetail[item.domId].length > 0
"
@click="handleClickTabItem('literature')"
:class="['tab-item', currentTab == 'literature' ? 'active' : '']"
>展览文献</span
>
</span>
</span>
</div>
<!-- 展览简介 -->
<div class="content-item display-detail_intro" id="intro">
<div class="intro-content">
<div class="intro-title">
<!-- <svg-icon icon-class="jianjie"></svg-icon> -->
<!-- <i class="el-icon-tickets"></i> -->
<span>展览简介</span>
</div>
<div class="intro-content">
<div class="left-box">简介</div>
<div
class="intro-content-container"
v-html="displayDetail.intro"
></div>
</div>
</div>
<div
class="display-detail_virtual content-item"
v-if="displayDetail.virtualVo.length > 0"
id="virtualVo"
>
<div class="custom_title">
<div class="center">
<!-- <svg-icon icon-class="wenxian"></svg-icon> -->
<span class="title">虚拟展厅</span>
</div>
</div>
<div class="vr-content">
<div
class="img-container"
@click="handleToVR(item)"
v-for="(item, index) in displayDetail.virtualVo"
:key="index"
>
<img :src="item.faceImagePressUrl" alt="" />
<div class="modal">
<svg-icon icon-class="360"></svg-icon>
<div class="name">点击进入{{ item.name }}</div>
</div>
</div>
</div>
</div>
<!-- 展览视频 -->
<div
id="videosVo"
class="content-item videos"
v-if="displayDetail.videosVo && displayDetail.videosVo.length > 0"
id="videos"
>
<div class="video-title">
<!-- <i class="el-icon-video-camera"></i> -->
......@@ -235,8 +239,8 @@
<div
class="content-item display-detail_units"
ref="units"
id="exhibitionUnits"
v-if="displayDetail.exhibitionUnits.length > 0"
id="exhibitionUnits"
>
<div class="custom_title">
<div class="center">
......@@ -338,34 +342,17 @@
</div>
</div>
<div
class="display-detail_virtual content-item"
v-if="displayDetail.virtualVo.length > 0"
>
<div
class="img-container"
@click="handleToVR(item)"
v-for="(item, index) in displayDetail.virtualVo"
:key="index"
>
<img :src="item.faceImagePressUrl" alt="" />
<div class="modal">
<svg-icon icon-class="360"></svg-icon>
<div class="name">点击进入{{ item.name }}</div>
</div>
</div>
</div>
<!--展览相关文物 -->
<div
class="content-item display-detail_relateRc"
ref="units"
id="relateRelics"
v-if="
displayDetail.culturalRelicVo &&
displayDetail.culturalRelicVo.length > 0
"
id="culturalRelicVo"
>
<div class="cr-title">展览相关文物</div>
<div class="cr-title">展览文物</div>
<SlideImageGroup :imgList="displayDetail.culturalRelicVo">
<template slot-scope="{ item }" slot="img">
<img
......@@ -388,10 +375,10 @@
<!-- 相关文献 -->
<div
class="content-item display-detail_lts"
id="literature"
v-if="
displayDetail.literatureVo && displayDetail.literatureVo.length > 0
"
id="literatureVo"
>
<div class="custom_title">
<div class="center">
......@@ -400,42 +387,23 @@
</div>
</div>
<div class="lts-content">
<el-table
:data="displayDetail.literatureVo"
:header-cell-style="{
background: '#eeeeee',
color: '#333',
}"
:row-style="tableRowStyle"
<div
class="lt-item"
v-for="(item, index) in displayDetail.literatureVo"
:key="index"
>
<el-table-column
prop="name"
label="名称"
align="center"
></el-table-column>
<el-table-column
prop="authors"
label="作者"
align="center"
></el-table-column>
<el-table-column
prop="date"
label="出版时间"
align="center"
></el-table-column>
<el-table-column
align="center"
prop="source"
label="出版所在刊物"
></el-table-column>
<el-table-column label="阅读" align="center">
<template slot-scope="scope">
<div class="pdf-img" @click="handleViewLt(scope.row)">
<img src="@/assets/imgs/display/ch/pdf-icon.png" />
<span class="lt-order">[{{ index + 1 }}]</span>
<span class="lt-authors" v-if="item.authors"
>{{ item.authors }}.</span
>
<span class="lt-name" v-if="item.name" @click="handleViewLt(item)"
>{{ item.authors }}.</span
>
<span class="lt-source" v-if="item.source"
>{{ item.source }}.</span
>
<span class="lt-date" v-if="item.date">{{ item.date }}</span>
</div>
</template>
</el-table-column>
</el-table>
</div>
</div>
</div>
......@@ -453,7 +421,7 @@ import AudioPlayer from "@/components/AudioPlayer";
import ReaderOperations from "@/components/ReaderOperations";
import Card from "@/views/personal/components/Card";
import Video from "@/components/Video";
import { getFullUrl, previewFile } from "@/utils/index";
import { previewFile } from "@/utils/index";
import ChStyleUnit from "./ChStyleUnit.vue";
import MenuList from "@/components/MenuList";
import videoPlayer from "@/components/VideoPlayer";
......@@ -461,6 +429,7 @@ import SlideImage from "@/components/SlideImage";
import SlideImageGroup from "@/components/SlideImageGroup";
import { swiper, swiperSlide } from "vue-awesome-swiper";
import "swiper/dist/css/swiper.css";
import { isElementInViewport2 } from "@/utils/index";
export default {
name: "BlueStyle",
components: {
......@@ -510,16 +479,56 @@ export default {
},
},
isFixed: false,
currentTab: "intro",
currentTab: null,
offsetTop: null,
tabbarData: [
{
name: "展览简介",
domId: "intro",
},
{
name: "虚拟展厅",
domId: "virtualVo",
},
{
name: "展览视频",
domId: "videosVo",
},
{
name: "展览单元",
domId: "exhibitionUnits",
},
{
name: "展览文物",
domId: "culturalRelicVo",
},
{
name: "相关文献",
domId: "literatureVo",
},
],
};
},
async mounted() {
this.loadDetail();
window.addEventListener("scroll", this.initHeight);
this.$nextTick(() => {
this.offsetTop = document.querySelector("#tabbar").offsetTop;
window.addEventListener("scroll", this.initHeight);
this.offsetTop = document.querySelector("#tabbar").offsetTop; //距离offsetParent的高度
this.tabbarData.map((item) => {
let dom = document.getElementById(item.domId);
if (dom) {
item.position = dom.offsetTop - 320; //100navbar 55tabbar
}
});
});
},
beforeRouteLeave(to, form, next) {
// 离开路由移除滚动事件
window.removeEventListener("scroll", this.initHeight);
next();
},
methods: {
async loadDetail() {
if (
......@@ -537,6 +546,13 @@ export default {
) {
this.currentVideo = this.displayDetail.videosVo[0];
}
if (this.displayDetail.intro) {
this.currentTab = {
name: "展览简介",
domId: "intro",
};
}
function processUnit(list) {
for (let o of list || []) {
if (o.children) {
......@@ -557,9 +573,6 @@ export default {
this.$message.info("正在播放当前文物讲解音频,点击旋转按钮可关闭");
this.$refs.AudioPlayer.play();
}
// const swiperThumbs = this.$refs.swiperThumbs.swiper;
// swiperThumbs.controller.control = swiperTop;
});
},
......@@ -589,18 +602,18 @@ export default {
};
},
// 关联文献的行样式调整
tableRowStyle({ row, rowIndex }) {
if (rowIndex % 2 == 0) {
return {
background: "#f9f9f9 !important",
};
} else {
return {
background: "#fff !important",
};
}
},
// // 关联文献的行样式调整
// tableRowStyle({ row, rowIndex }) {
// if (rowIndex % 2 == 0) {
// return {
// background: "#f9f9f9 !important",
// };
// } else {
// return {
// background: "#fff !important",
// };
// }
// },
// 预览关联文献
handleViewLt(item) {
......@@ -654,10 +667,10 @@ export default {
},
handleClickTabItem(item) {
console.log(item);
this.currentTab = item;
let el = document.getElementById(item);
el.scrollIntoView({ block: "center", behavior: "smooth" });
if (item.position) {
document.documentElement.scrollTop = item.position;
}
},
initHeight() {
......@@ -665,7 +678,13 @@ export default {
window.pageYOffset ||
document.documentElement.scrollTop ||
document.body.scrollTop;
this.isFixed = scrollTop > this.offsetTop ? true : false;
this.isFixed = scrollTop > this.offsetTop - 155 ? true : false; //100为navbar的高度,55为tabbar的高度
this.tabbarData.map((item) => {
let content = document.getElementById(item.domId);
if (content && isElementInViewport2(content)) {
this.currentTab = item;
}
});
},
},
};
......@@ -730,31 +749,9 @@ $titleFontFamily: SourceHanSerifCN-Bold;
font-size: 26px;
font-weight: 400;
color: $themeColor;
line-height: 101px;
font-family: "SourceHanSerifCN-Bold";
}
}
.desc {
flex: 1;
display: flex;
align-items: center;
.modify {
width: 16px;
margin: 0 6px;
img {
width: 100%;
}
}
.divider {
flex: 1;
height: 6px;
background: url("@/assets/imgs/display/normal/divider.png") 100% 100%
repeat-x;
img {
width: 100%;
}
}
}
}
.enlarge {
......@@ -777,6 +774,13 @@ $titleFontFamily: SourceHanSerifCN-Bold;
height: 24px;
}
}
.isFixed {
position: fixed;
left: 0;
top: 100px;
z-index: 99;
}
/**公共样式结束 */
/**样式开始 */
......@@ -812,8 +816,9 @@ $titleFontFamily: SourceHanSerifCN-Bold;
align-items: center;
justify-content: center;
min-height: 200px;
position: relative;
// position: relative;
margin: 0 70px;
padding-bottom: 56px;
/**基本信息 */
.display-detail_basic_info {
position: relative;
......@@ -1004,20 +1009,17 @@ $titleFontFamily: SourceHanSerifCN-Bold;
/**简介和视频 */
.display-detail_intro {
// background-image: url("@/assets/imgs/display/normal/bg.png");
background-size: 1%;
// display: flex;
.intro-content {
// background-size: 1%;
padding: 40px;
line-height: 28px;
.intro-title {
font-size: 26px;
font-weight: 400;
color: #2069c4;
line-height: 90px;
font-family: "SourceHanSerifCN-Bold";
display: flex;
// justify-content: center;
align-items: center;
margin-bottom: 32px;
i {
margin-right: 10px;
}
......@@ -1026,9 +1028,28 @@ $titleFontFamily: SourceHanSerifCN-Bold;
font-size: 36px;
}
}
.intro-content {
line-height: 28px;
display: flex;
}
.left-box {
width: 60px;
background-color: $themeColor;
min-height: 200px;
color: #fff;
font-size: 28px;
writing-mode: vertical-rl;
display: flex;
align-items: center;
justify-content: center;
letter-spacing: 10px;
font-family: SourceHanSerifCN-Bold;
}
.intro-content-container {
flex: 1;
text-indent: 34px;
}
padding: 16px 32px;
background-color: rgba($themeColor, 10%);
}
}
// 视频
......@@ -1042,7 +1063,8 @@ $titleFontFamily: SourceHanSerifCN-Bold;
align-items: center;
font-size: 24px;
color: $themeColor;
padding: 40px;
padding: 0 40px;
margin-bottom: 32px;
font-family: SourceHanSerifCN-Bold;
i {
font-size: 28px;
......@@ -1104,7 +1126,7 @@ $titleFontFamily: SourceHanSerifCN-Bold;
}
}
.video-box {
height: 600px;
height: 500px;
.video-player {
height: 100%;
}
......@@ -1113,8 +1135,10 @@ $titleFontFamily: SourceHanSerifCN-Bold;
// 虚拟展
.display-detail_virtual {
height: 400px;
margin-bottom: 56px;
.vr-content {
display: flex;
}
.img-container {
// width: 800px;
flex: 1;
......@@ -1193,7 +1217,7 @@ $titleFontFamily: SourceHanSerifCN-Bold;
text-overflow: ellipsis;
overflow: hidden;
width: 100%;
white-space:nowrap;
white-space: nowrap;
}
.active {
......@@ -1318,11 +1342,11 @@ $titleFontFamily: SourceHanSerifCN-Bold;
// 关联文物
.display-detail_relateRc {
padding: 0 40px;
margin-top:40px;
margin-bottom: 56px;
.cr-title {
display: flex;
align-items: center;
font-size: 24px;
font-size: 26px;
color: $themeColor;
font-family: SourceHanSerifCN-Bold;
i {
......@@ -1362,9 +1386,19 @@ $titleFontFamily: SourceHanSerifCN-Bold;
/**关联文献 */
.display-detail_lts {
// background-color: #fafafa;
.lts-content {
// flex: 1;
padding: 0 40px 40px;
.lt-item {
border-bottom: 1px dashed #ccc;
padding-bottom: 9px;
& > span {
padding: 0 4px;
}
}
.lt-name {
color: #2069c4;
cursor: pointer;
}
}
}
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论