Browse Source

知行学院PC界面优化

local_v3_liwenxuan
liwenxuan 2 years ago
parent
commit
8fe044a416
  1. 176
      src/api/knowledge/scroll.js
  2. 2
      src/layout/components/AppMain.vue
  3. 10
      src/views/knowledge/knowledge/components/KnowledgeContent.vue
  4. 4
      src/views/knowledge/knowledge/components/Navili.vue
  5. 131
      src/views/knowledge/knowledge/index.vue
  6. 131
      src/views/knowledge/news/index.vue

176
src/api/knowledge/scroll.js

@ -4,98 +4,100 @@
export function onScroll() {
// 获取所有锚点元素
const navContents = document.querySelectorAll('.models')
// 所有锚点元素的 offsetTop
const offsetTopArr = []
navContents.forEach(item => {
offsetTopArr.push(item.offsetTop)
})
// 获取当前文档流的 scrollTop
const scrollTop = document.documentElement.scrollTop || document.body.scrollTop
// 定义当前点亮的导航下标
let navIndex = 0
for (let n = 0; n < offsetTopArr.length; n++) {
// 如果 scrollTop 大于等于第n个元素的 offsetTop 则说明 n-1 的内容已经完全不可见
// 那么此时导航索引就应该是n了
if (scrollTop+210 >= offsetTopArr[n]) {
navIndex = n
}
//若滚动条已经到底则直接激活最后一个导航
if (scrollTop + document.documentElement.clientHeight === document.documentElement.scrollHeight) {
navIndex = offsetTopArr.length - 1;
}
// 获取所有锚点元素
const navContents = document.querySelectorAll('.models')
// 所有锚点元素的 offsetTop
const offsetTopArr = []
navContents.forEach(item => {
offsetTopArr.push(item.offsetTop)
})
// 获取当前文档流的 scrollTop
//const scrollTop = document.documentElement.scrollTop || document.body.scrollTop
const scrollTop = document.querySelector('.app-container').scrollTop || document.body.scrollTop
// 定义当前点亮的导航下标
let navIndex = 0
for (let n = 0; n < offsetTopArr.length; n++) {
// 如果 scrollTop 大于等于第n个元素的 offsetTop 则说明 n-1 的内容已经完全不可见
// 那么此时导航索引就应该是n了
if (scrollTop + 210 >= offsetTopArr[n]) {
navIndex = n
}
//active.value = navIndex
return navIndex;
}
// 跳转到指定索引的元素
export function scrollTo(index) {
// 获取目标的 offsetTop
// css选择器是从 1 开始计数,我们是从 0 开始,所以要 +1
const targetOffsetTop = document.querySelector(`.content .models:nth-child(${index + 1})`).offsetTop
// 获取当前 offsetTop
let scrollTop = document.documentElement.scrollTop || document.body.scrollTop
// 定义一次跳 150 个像素
const STEP = 50
// 判断是往下滑还是往上滑
if (scrollTop > targetOffsetTop) {
// 往上滑
smoothUp()
} else {
// 往下滑
smoothDown()
//若滚动条已经到底则直接激活最后一个导航
if (scrollTop + document.documentElement.clientHeight === document.documentElement.scrollHeight) {
navIndex = offsetTopArr.length - 1;
}
// 定义往下滑函数
function smoothDown() {
// 如果当前 scrollTop 小于 targetOffsetTop 说明视口还没滑到指定位置
if (scrollTop < targetOffsetTop) {
// 如果和目标相差距离大于等于 STEP 就跳 STEP
// 否则直接跳到目标点,目标是为了防止跳过了。
if (targetOffsetTop - scrollTop >= STEP) {
scrollTop += STEP
} else {
scrollTop = targetOffsetTop
}
document.body.scrollTop = scrollTop
document.documentElement.scrollTop = scrollTop
// 关于 requestAnimationFrame 可以自己查一下,在这种场景下,相比 setInterval 性价比更高
requestAnimationFrame(smoothDown)
}
//active.value = navIndex
return navIndex;
}
// 跳转到指定索引的元素
/* export function scrollTo(index) {
// 获取目标的 offsetTop
// css选择器是从 1 开始计数,我们是从 0 开始,所以要 +1
const targetOffsetTop = document.querySelector(`.content .models:nth-child(${index + 1})`).offsetTop
// 获取当前 offsetTop
let scrollTop = document.documentElement.scrollTop || document.body.scrollTop
// 定义一次跳 150 个像素
const STEP = 50
// 判断是往下滑还是往上滑
if (scrollTop > targetOffsetTop) {
// 往上滑
smoothUp()
} else {
// 往下滑
smoothDown()
}
// 定义往下滑函数
function smoothDown() {
// 如果当前 scrollTop 小于 targetOffsetTop 说明视口还没滑到指定位置
if (scrollTop < targetOffsetTop) {
// 如果和目标相差距离大于等于 STEP 就跳 STEP
// 否则直接跳到目标点,目标是为了防止跳过了。
if (targetOffsetTop - scrollTop >= STEP) {
scrollTop += STEP
} else {
scrollTop = targetOffsetTop
}
document.body.scrollTop = scrollTop
document.documentElement.scrollTop = scrollTop
// 关于 requestAnimationFrame 可以自己查一下,在这种场景下,相比 setInterval 性价比更高
requestAnimationFrame(smoothDown)
}
// 定义往上滑函数
function smoothUp() {
if (scrollTop > targetOffsetTop) {
if (scrollTop - targetOffsetTop >= STEP) {
scrollTop -= STEP
} else {
scrollTop = targetOffsetTop
}
document.body.scrollTop = scrollTop
document.documentElement.scrollTop = scrollTop
requestAnimationFrame(smoothUp)
}
// 定义往上滑函数
function smoothUp() {
if (scrollTop > targetOffsetTop) {
if (scrollTop - targetOffsetTop >= STEP) {
scrollTop -= STEP
} else {
scrollTop = targetOffsetTop
}
document.body.scrollTop = scrollTop
document.documentElement.scrollTop = scrollTop
requestAnimationFrame(smoothUp)
}
}
export function formatDate(timestamp) {
var date = new Date(timestamp * 1000);//时间戳为10位需*1000,时间戳为13位的话不需乘1000
var Y = date.getFullYear() + '-';
var M = (date.getMonth()+1 < 10 ? '0'+(date.getMonth()+1) : date.getMonth()+1) + '-';
var D = date.getDate() + ' ';
var h = date.getHours() + ':';
var m = date.getMinutes() + ':';
var s = date.getSeconds();
return Y+M+D+h+m+s;
}
} */
export function formatDate(timestamp) {
var date = new Date(timestamp * 1000);//时间戳为10位需*1000,时间戳为13位的话不需乘1000
var Y = date.getFullYear() + '-';
var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
var D = date.getDate() + ' ';
var h = date.getHours() + ':';
var m = date.getMinutes() + ':';
var s = date.getSeconds();
return Y + M + D + h + m + s;
}

2
src/layout/components/AppMain.vue

@ -34,7 +34,7 @@ const tagsViewStore = useTagsViewStore();
.hasTagsView {
.app-main {
/* 84 = navbar + tags-view = 50 + 34 */
min-height: calc(100vh - 84px);
min-height: calc(100vh - 85px);
}
.fixed-header + .app-main {

10
src/views/knowledge/knowledge/components/KnowledgeContent.vue

@ -1,5 +1,5 @@
<script setup lang='ts'>
import { onScroll, scrollTo, formatDate } from '@/api/knowledge/scroll'
import { formatDate } from '@/api/knowledge/scroll'
@ -46,11 +46,7 @@ watch(() => props.isShow, () => {
//console.log(pdfIframeShow.value)
}
})
onMounted(() => {
/* const gTestUrl = props.contentSource?.gTestUrl;
const gContent = props.contentSource?.gContent; */
});
</script>
@ -76,11 +72,11 @@ onMounted(() => {
<style>
.dialogStyle {
top:-9.9%;
top: -9.9%;
height: auto;
width: auto;
max-width: 1000px;
}
.my-header {

4
src/views/knowledge/knowledge/components/Navili.vue

@ -1,5 +1,5 @@
<script lang='ts' setup>
import { scrollTo } from '@/api/knowledge/scroll'
const showli = ref(true);
const props = defineProps({
oneli: {
@ -25,7 +25,7 @@ const props = defineProps({
</script>
<template>
<li :class="{ active: active === index }" @click="scrollTo(index)" v-if="showli">
<li :class="{ active: active === index }" v-if="showli">
{{ oneli?.atTitle }}
</li>
</template>

131
src/views/knowledge/knowledge/index.vue

@ -7,7 +7,7 @@ import Archivestype from '@/views/knowledge/knowledge/components/archivestype.vu
import Navili from './components/Navili.vue'
import KnowledgeContent from './components/KnowledgeContent.vue'
import { UserQuery, UserDetail, NaviQuery, Navi, Graphicform, PageParam } from '@/api/knowledge/types'
import { onScroll, scrollTo, formatDate } from '@/api/knowledge/scroll'
import { onScroll, formatDate } from '@/api/knowledge/scroll'
import { useRouter } from 'vue-router'
import errimg from '@/assets/404_images/imgNotFound.png'
@ -83,7 +83,26 @@ onBeforeMount(() => {
onMounted(() => {
//
window.addEventListener('scroll', jsScroll, false)
//window.addEventListener('scroll', jsScroll, false)
document.querySelector('.app-container')!.addEventListener('scroll', jsScroll, false)
document.querySelector('.navs')!.addEventListener('wheel', (e) => {
//
e.preventDefault()
}, {
//falsetrue
passive: false,
}) //has-logo sidebar-container
document.querySelector('.sidebar-container')!.addEventListener('wheel', (e) => {
//
e.preventDefault()
}, {
//falsetrue
passive: false,
})
if (routerUrl.endsWith("index")) {//
naviQueryParam.atParentId = '16213848089876281'
@ -95,9 +114,9 @@ onMounted(() => {
getZxxyNavis(naviQueryParam)
.then(({ data }) => {
naviList.value = data
}).finally(() => {
fatherisReady.value = 100;
})
}).finally(() => {
fatherisReady.value = 100;
})
//
getTuijian(pageParamTuijian)
.then(({ data }) => {
@ -141,10 +160,39 @@ function showContentDialog(item: any) {
}
// start
function scrollTo(index: any) {
nextTick(() => {
//console.log(index)
const ele = document?.querySelector<HTMLElement>(`.content .models:nth-child(${index + 1})`)!
ele.scrollIntoView()
active.value = index
})
}
// end
</script>
<template>
<div class="app-container">
<KnowledgeContent v-model:isShow="showContentBox" :contentSource="cardContentSource"></KnowledgeContent>
<!-- 导航区域 -->
<div class="uldiv">
<ul class="navs">
<li :class="{ active: active === 0 }" @click="scrollTo(0)">
推荐
</li>
<template v-for="(item, index) in naviList">
<Navili :class="{ active: active === index+1 }" :oneli=item :index=(index+1) v-if="item.hasCard" :active=active
@click="scrollTo(index + 1)"></Navili>
</template>
</ul>
</div>
<!-- 内容区域 -->
<div class="content">
@ -194,70 +242,82 @@ function showContentDialog(item: any) {
</template>
</div>
<!-- 内容详情组件 -->
<KnowledgeContent v-model:isShow="showContentBox" :contentSource="cardContentSource"></KnowledgeContent>
<!-- 导航区域 -->
<ul class="navs">
<li :class="{ active: active === 0 }" @click="scrollTo(0)">
推荐
</li>
<template v-for="(item, index) in naviList">
<Navili :class="{ active: active === index+1 }" :oneli=item :index=(index+1) v-if="item.hasCard" :active=active
@click="scrollTo(index + 1)"></Navili>
</template>
</ul>
</div>
</template>
<style scoped>
.app-container {
height: calc(100vh - 125px);
width: 100%;
overflow: auto;
padding: 0 10px 0 30px;
display: grid;
/* 声明了三列,宽度分别为 200px 100px 200px */
grid-template-columns: 200px auto;
}
.content {
background-color: white;
width: 89.1%;
margin-left: 190px;
width: auto;
max-width: 87%;
padding-left: 9%;
box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
border-radius: 5px;
}
h3 {
margin-left: 10px;
}
/* 导航栏的样式 */
.navs {
width: 192px;
width: 142px;
position: fixed;
height: auto;
top: 95px;
top: 105px;
text-align: center;
line-height: 5;
font-size: 11.5px;
color: #909399;
background-color: white;
padding: 10px;
border-radius: 9.5px;
box-shadow: rgba(0, 0, 0, 0.04) 0px 2px 5px;
}
.navs li {
text-align: center;
line-height: 3;
li {
padding-left: 12px;
text-align: left;
line-height: 2.7;
font-size: 15.5px;
color: #909399;
background-color: white;
margin-right: 15px;
}
.navs li:hover {
li:hover {
cursor: pointer;
background-color: #F2F3F5;
color: #409EFF;
border-radius: 6px;
}
/* 当导航被点亮后改变颜色 */
.navs .active {
color: #409EFF;
background-color: #EAF2FF;
border-radius: 6px;
}
.model-title {
@ -293,6 +353,7 @@ function showContentDialog(item: any) {
border-radius: 15px;
width: 480px;
height: 290px;
}
.card-right {

131
src/views/knowledge/news/index.vue

@ -7,7 +7,7 @@ import Archivestype from '@/views/knowledge/knowledge/components/archivestype.vu
import Navili from '@/views/knowledge/knowledge/components/Navili.vue'
import KnowledgeContent from '@/views/knowledge/knowledge/components/KnowledgeContent.vue'
import { UserQuery, UserDetail, NaviQuery, Navi, Graphicform, PageParam } from '@/api/knowledge/types'
import { onScroll, scrollTo, formatDate } from '@/api/knowledge/scroll'
import { onScroll, formatDate } from '@/api/knowledge/scroll'
import { useRouter } from 'vue-router'
import errimg from '@/assets/404_images/imgNotFound.png'
@ -83,7 +83,26 @@ onBeforeMount(() => {
onMounted(() => {
//
window.addEventListener('scroll', jsScroll, false)
//window.addEventListener('scroll', jsScroll, false)
document.querySelector('.app-container')!.addEventListener('scroll', jsScroll, false)
document.querySelector('.navs')!.addEventListener('wheel', (e) => {
//
e.preventDefault()
}, {
//falsetrue
passive: false,
}) //has-logo sidebar-container
document.querySelector('.sidebar-container')!.addEventListener('wheel', (e) => {
//
e.preventDefault()
}, {
//falsetrue
passive: false,
})
if (routerUrl.endsWith("index")) {//
naviQueryParam.atParentId = '16213848089876281'
@ -95,9 +114,9 @@ onMounted(() => {
getZxxyNavis(naviQueryParam)
.then(({ data }) => {
naviList.value = data
}).finally(() => {
fatherisReady.value = 100;
})
}).finally(() => {
fatherisReady.value = 100;
})
//
getTuijian(pageParamTuijian)
.then(({ data }) => {
@ -141,10 +160,39 @@ function showContentDialog(item: any) {
}
// start
function scrollTo(index: any) {
nextTick(() => {
//console.log(index)
const ele = document?.querySelector<HTMLElement>(`.content .models:nth-child(${index + 1})`)!
ele.scrollIntoView()
active.value = index
})
}
// end
</script>
<template>
<div class="app-container">
<KnowledgeContent v-model:isShow="showContentBox" :contentSource="cardContentSource"></KnowledgeContent>
<!-- 导航区域 -->
<div class="uldiv">
<ul class="navs">
<li :class="{ active: active === 0 }" @click="scrollTo(0)">
推荐
</li>
<template v-for="(item, index) in naviList">
<Navili :class="{ active: active === index+1 }" :oneli=item :index=(index+1) v-if="item.hasCard" :active=active
@click="scrollTo(index + 1)"></Navili>
</template>
</ul>
</div>
<!-- 内容区域 -->
<div class="content">
@ -194,70 +242,82 @@ function showContentDialog(item: any) {
</template>
</div>
<!-- 内容详情组件 -->
<KnowledgeContent v-model:isShow="showContentBox" :contentSource="cardContentSource"></KnowledgeContent>
<!-- 导航区域 -->
<ul class="navs">
<li :class="{ active: active === 0 }" @click="scrollTo(0)">
推荐
</li>
<template v-for="(item, index) in naviList">
<Navili :class="{ active: active === index+1 }" :oneli=item :index=(index+1) v-if="item.hasCard" :active=active
@click="scrollTo(index + 1)"></Navili>
</template>
</ul>
</div>
</template>
<style scoped>
.app-container {
height: calc(100vh - 125px);
width: 100%;
overflow: auto;
padding: 0 10px 0 30px;
display: grid;
/* 声明了三列,宽度分别为 200px 100px 200px */
grid-template-columns: 200px auto;
}
.content {
background-color: white;
width: 89.1%;
margin-left: 190px;
width: auto;
max-width: 87%;
padding-left: 9%;
box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
border-radius: 5px;
}
h3 {
margin-left: 10px;
}
/* 导航栏的样式 */
.navs {
width: 192px;
width: 142px;
position: fixed;
height: auto;
top: 95px;
top: 105px;
text-align: center;
line-height: 5;
font-size: 11.5px;
color: #909399;
background-color: white;
padding: 10px;
border-radius: 9.5px;
box-shadow: rgba(0, 0, 0, 0.04) 0px 2px 5px;
}
.navs li {
text-align: center;
line-height: 3;
li {
padding-left: 12px;
text-align: left;
line-height: 2.7;
font-size: 15.5px;
color: #909399;
background-color: white;
margin-right: 15px;
}
.navs li:hover {
li:hover {
cursor: pointer;
background-color: #F2F3F5;
color: #409EFF;
border-radius: 6px;
}
/* 当导航被点亮后改变颜色 */
.navs .active {
color: #409EFF;
background-color: #EAF2FF;
border-radius: 6px;
}
.model-title {
@ -293,6 +353,7 @@ function showContentDialog(item: any) {
border-radius: 15px;
width: 480px;
height: 290px;
}
.card-right {

Loading…
Cancel
Save