如何实现图片点击展示大图

861 阅读2分钟

如何实现图片点击展示大图

最近在项目中遇到一个问题,通过富文本编辑器编写的内容,在展示时,图片会出现模糊的情况(因为展示富文本编辑器内容的宽度是固定的,图片会出现压缩的情况)。

问题:图片宽度被压缩,图片展示不清楚

思路:图片既然展示不清楚,那就让图片可以自由放大解决问题。通过给富文本编辑器内容的容器绑定点击事件,点击图片时可以获取图片的url,有了图片的url,图片自由放大的问题就可以解决了,我们可以用element组件库el-image组件来实现这个图片自由放大的效果,也可以自己写组件。

html 内容

 <div v-dompurify-html="noticeInfo.noticeContent"
           @click="handClick"
           class="notice-html">
 </div>  
  <el-image style="width: 0; height: 0"
                ref="elImg"
                :src="imgSrc"
                :preview-src-list="imgsSrcList">
  </el-image>

v-dompurify-html是一个防止xss注入的插件

imgSrc: 动态展示大图的图片地址

handClick: 富文本编辑器的容器点击事件

imgsSrcList: 富文本编辑器内容的图片地址列表

js内容

  handClick($event) {
    if ($event.target.nodeName === 'IMG') {
      this.imgSrc = $event.target.currentSrc
      this.$refs.elImg.clickHandler()
    }
  },

通过时事件对象获取当前点击的元素,判断节点类型是否是图片,如果是,通过事件对象获取图片地址,复制给el-image的组件的src属性,并且触发el-image组件的点击事件。

  handGetImgList() {
    const noticeHtml = document.querySelector('.notice-html')
    const imgs = noticeHtml.querySelectorAll('img')
    this.imgsSrcList = Array.from(imgs).map(item => item.src)
  }

获取富文本编辑器容器的所有图片元素,并且获取图片元素的url,得到一个图片地址数组。该列表可以在查看图片大图时,切换页面中的图片。具体效果可参考el-image组件

完整代码

<template>
  <div class="notice-content">
    <h2>{{noticeInfo.noticeTitle}}</h2>
    <el-image style="width: 0; height: 0"
              ref="elImg"
              :src="imgSrc"
              :preview-src-list="imgsSrcList">
    </el-image>
    <div style="overflow:auto">
      <div v-dompurify-html="noticeInfo.noticeContent"
           @click="handClick"
           class="notice-html">
      </div>
    </div>

  </div>
</template>

<script>
export default {
  name: 'NoticeContent',
  props: {
    noticeInfo: {
      type: Object,
      default() {
        return {}
      }
    }
  },
  data() {
    return {
      imgsSrcList: [],
      imgSrc: ''
    }
  },
  mounted() {
    this.handGetImgList()
  },
  methods: {
    handClick($event) {
      if ($event.target.nodeName === 'IMG') {
        this.imgSrc = $event.target.currentSrc
        this.$refs.elImg.clickHandler()
      }
    },
    handGetImgList() {
      const noticeHtml = document.querySelector('.notice-html')
      const imgs = noticeHtml.querySelectorAll('img')
      this.imgsSrcList = Array.from(imgs).map(item => item.src)
    }
  }
}
</script>

<style lang="scss" rel="stylesheet/scss" scoped>
.notice-content {
  padding: 32px 48px 32px 62px;
  height: 100%;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  .notice-html {
    overflow: auto;
    height: 100%;
  }
}
</style>
<style lang="scss" rel="stylesheet/scss">
//  因为富文本编辑器内容是在另外一个系统中编辑的,全局样式会影响内容的展现,所以需要统一标准
.notice-html {
  overflow: auto;
  line-height: 1.5;
  font-size: 12px;
  h1,
  h2,
  h3,
  h4,
  h5,
  h6 {
    margin: 0;
    padding: 0;
    font-weight: 600;
    line-height: 1.5;
  }
  li,
  p {
    margin: 0;
    padding: 0;
  }
  img {
    max-width: 100%;
    // cursor: pointer;
  }
  ul {
    padding-left: 20px;
  }
  ul > li {
    list-style: disc;
  }
  ol > li {
    list-style: decimal;
  }
}
</style>

结语

主要是工作中问题的一些个人记录,文章比较简单,没什么难点,个人的一些实现思路。