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

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

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