个商个体户可以建设网站不,怎么样做免费的百度seo,林壑地板北京网站建设,什么网站系统做的最好的Vue实现悬浮图片弹出大图预览弹窗#xff0c;弹窗顶部与图片顶部平齐 需求背景
当前项目内某页面左侧展示图片列表#xff0c;图片列表展示的均为小图。需求希望鼠标移动到对应图片时#xff0c;右侧出现大图预览弹窗#xff0c;且该弹窗顶部需与图片顶部平齐。同时弹窗要…Vue实现悬浮图片弹出大图预览弹窗弹窗顶部与图片顶部平齐 需求背景
当前项目内某页面左侧展示图片列表图片列表展示的均为小图。需求希望鼠标移动到对应图片时右侧出现大图预览弹窗且该弹窗顶部需与图片顶部平齐。同时弹窗要在页面中展示完全不能超出窗口高度导致被遮挡
核心实现
1.获取悬浮图片的位置信息
div classimage_item v-for(item, index) in imgList :keyindeximg:srcitemclassimgmouseentere handlePreview(e, item)mouseleavepreview.show false/
/div// 获取当前图片顶部与视口顶部的距离top和底部的距离bottom
const handlePreview (e, url) {const targetRect e.target.getBoundingClientRect()preview.bottom window.innerHeight - targetRect.toppreview.top targetRect.toppreview.url urlpreview.show true
}2.动态计算大图预览弹窗位置
!-- 样式绑定计算属性根据悬浮图片位置变化 --
div classmodule_view v-showpreview.show :stylepreviewStyleimg :srcpreview.url classimg /
/divconst previewStyle computed(() {// 弹窗实际高度const previewHeight 538const container listRef.value// 容器与视口顶部距离const containerTop container ? container.getBoundingClientRect().top : 0const previewTop preview.topconst previewBottom preview.bottom// 弹窗顶部与容器顶部的距离let top previewTop - containerToplet bottom previewBottom - previewHeight// 判断弹窗顶部与视口底部的距离是否能容纳整个弹窗if (bottom 0) {// 无法容纳时减小弹窗顶部距离容器顶部的距离从而抬升弹窗// 还需判断抬升后弹窗顶部与视口顶部是否仍大于0否则设置为置顶距离即负的容器与视口顶部距离top previewTop bottom 0 ? top bottom : 0 - containerTop}return {top: top px}
})完整代码
!-- 实现图片悬浮右侧展开预览大图弹窗功能弹窗顶部与图片顶部平齐 --
templatediv classimage_viewdiv classimage_list reflistRefdiv classimage_item v-for(item, index) in imgList :keyindeximg:srcitemclassimgmouseentere handlePreview(e, item)mouseleavepreview.show false//divdiv classmodule_view v-showpreview.show :stylepreviewStyleimg :srcpreview.url classimg //div/div/div
/templatescript
import { defineComponent, ref, reactive, computed } from vue
import { getImg } from /utils/imgExampleexport default defineComponent({setup() {const imgList ref(getImg(0, 12))const listRef ref(null)const preview reactive({top: 0,bottom: 0,url: ,show: false})const previewStyle computed(() {// 弹窗实际高度const previewHeight 538const container listRef.value// 容器与视口顶部距离const containerTop container ? container.getBoundingClientRect().top : 0const previewTop preview.topconst previewBottom preview.bottom// 弹窗顶部与容器顶部的距离let top previewTop - containerToplet bottom previewBottom - previewHeight// 判断弹窗顶部与视口底部的距离是否能容纳整个弹窗if (bottom 0) {// 无法容纳时减小弹窗顶部距离容器顶部的距离从而抬升弹窗// 还需判断抬升后弹窗顶部与视口顶部是否仍大于0否则设置为置顶距离即负的容器与视口顶部距离top previewTop bottom 0 ? top bottom : 0 - containerTop}return {top: top px}})// 获取当前图片顶部与视口顶部的距离top和底部的距离bottomconst handlePreview (e, url) {const targetRect e.target.getBoundingClientRect()preview.bottom window.innerHeight - targetRect.toppreview.top targetRect.toppreview.url urlpreview.show true}return {listRef,imgList,preview,previewStyle,handlePreview}}
})
/scriptstyle langless scoped
.image_view {width: 100%;height: 100%;.image_list {position: relative;width: 404px;height: 100%;padding: 12px;border: 1px solid #ededed;display: flex;flex-wrap: wrap;gap: 8px;.image_item {width: 120px;height: 120px;border-radius: 4px;overflow: hidden;.img {width: 100%;height: 100%;object-fit: cover;}}.module_view {position: absolute;top: 0;right: -404px;width: 400px;height: 528px;background: #fff;box-shadow: 0 4px 10px 2px rgba(0, 0, 0, 0.16);padding: 8px;border-radius: 12px;}}
}
/style