浮层展示信息位置处理

效果图

浮层展示信息位置处理_第1张图片
浮层展示信息位置处理_第2张图片

代码

<template>
  <div>
    <ul class="info-wrap">
      <li
        v-for="(item, index) in list"
        :key="item.id"
        class="info-item"
      >
        <div 
          class="base-info"
          @mouseenter="showDetailInfo($event, index)"
          @mouseleave="closeDetailInfo(index)"
        >基本信息div>
        <div 
          v-show="item.showDetail"
          :class="[
            'detail-info', 
            item.className
          ]" 
        >详细信息div>
      li>
    ul>
  div>
template>

<script>
export default {
  data() {
    return {
      list: [
        { id: 1 },
        { id: 2 },
        { id: 3 },
        { id: 4 },
        { id: 5 },
        { id: 6 },
        { id: 7 },
        { id: 8 },
        { id: 9 },
        { id: 10 },
      ]
    }
  },
  methods: {
    showDetailInfo(event, index) {

      // 总容器宽度,去掉滚动条、border
      const {
        clientWidth: containerWidth,
      } = document.querySelector('.info-wrap');

      // 目标容器
      const targetDom = event.target.parentNode.getBoundingClientRect();

      // 总容器
      const containerDom = document.querySelector('.info-wrap').getBoundingClientRect();

      // 可用宽度:因为有滚动条的存在
      const availableWidth = containerWidth + containerDom.left - targetDom.right;
      // 可用高度
      const availableHeight = containerDom.bottom - targetDom.top;

      console.log(`可用宽度:${availableWidth}`, `可用高度:${availableHeight}`)

      // 详情信息 10为间距
      const detailWidth = 300 + 10;
      const detailHeight = 300 + 10;

      let className = {}
      if (availableWidth > detailWidth) {
        className.right = true
      } else {
        className.left = true
      }

      if (availableHeight > detailHeight) {
        className.top = true;
      } else {
        className.bottom = true;
      }

      this.list.splice(index, 1, {
        ...this.list[index],
        showDetail: true,
        className
      })
    },
    closeDetailInfo(index) {
      this.$set(this.list[index], 'showDetail', false)
    }
  }
}
script>

<style scoped lang="less">
.info-wrap {
  width: 1000px;
  margin: 50px auto;
  height: 400px;
  overflow: auto;
  display: flex;
  flex-wrap: wrap;
  
}
.info-item {
  width: 200px;
  height: 200px;
  background: #ccc;
  margin-right: 10px;
  margin-bottom: 10px;
  position: relative;
}
.base-info {
  width: 200px;
  height: 200px;
  line-height: 200px;
  text-align: center;
}
.detail-info {
  position: absolute;
  z-index: 999;
  width: 300px;
  height: 300px;
  background: skyblue;
  line-height: 300px;
  text-align: center;
  &::after {
    content: '';
    width: 10px;
    height: 10px;
    background: skyblue;
    position: absolute;
    transform: rotate(45deg);
  }
  &.left {
    right: 210px;
    &::after {
      right: -5px
    }
  }
  &.right {
    left: 210px;
    &::after {
      left: -5px;
    }
  }
  &.top {
    top: 0;
    &::after {
      top: 20px;
    }
  }
  &.bottom {
    bottom: 0;
    &::after {
      bottom: 20px;
    }
  }
}
style>

你可能感兴趣的:(vue,Javascript,javascript,前端,css)