viewerjs如何多次初始化

1 问题背景

做web前端开发的总会用到图片查看器,就是点击查看大图的功能。对于大厂,肯定是自己实现一套图片查看器,但对于个人开发者,时间、精力、技术都有限,自己实现一套不现实,还是引用第三方库比较实际。其中viewerjs几乎是开源出来的图片查看器中功能最全的库,截止目前Github上的小星星已经有7.4k。

对于viewerjs的使用非常简单,如果不需要个性化配置的话,两三行js代码就能初始化。

<!-- a block container is required -->
<template>
  <div>
    <ul id="images">
      <li><img src="picture-1.jpg" alt="Picture 1"></li>
      <li><img src="picture-2.jpg" alt="Picture 2"></li>
      <li><img src="picture-3.jpg" alt="Picture 3"></li>
    </ul>
  </div>
</template>

<script>
import 'viewerjs/dist/viewer.css';
import Viewer from 'viewerjs';

const viewerjs = new Viewer(document.getElementById('images'));

</script>

在做卧卷想法时,由于每一条想法的图片集合都应该是一个独立的数据集,自然而然就想到针对每一条动态都初始化一个viewerjs。然后在测试的时候发现,除了第一条想法的图片查看器是正常的,其他想法均无法打开图片查看器。这是由于viewerjs的初始化过程在同一个页面只能执行一次,即使是在组件里初始化,只要这些组件都在同一个页面使用,就不能这样简单粗暴再次初始化viewerjs,这也算是viewerjs一个小小的不足之处。

2 解决方案

viewerjs有一个destroy( )方法,用于销毁viewerjs实例。

destroy( ): Destroy the viewer and remove the instance.

如图所示,想法的图片集合最外层是一个div,对这个div绑定一个唯一的id,并绑定一个在捕获阶段触发的点击事件。在点击事件中,首先判断变量viewerjs是否为null,如果不为null,则先执行destroy( )方法销毁,然后重新进行一次初始化。此处代码实例使用Vue作为框架。

<template>
  <div id="id" @click.capture="initViewerjs">
    <ul id="images">
      <li><img src="picture-1.jpg" alt="Picture 1"></li>
      <li><img src="picture-2.jpg" alt="Picture 2"></li>
      <li><img src="picture-3.jpg" alt="Picture 3"></li>
    </ul>
  </div>
</template>

<script>
import 'viewerjs/dist/viewer.css';
import Viewer from 'viewerjs';

let viewerjs = null
initViewerjs() {
  if (viewerjs !== null) {
    viewerjs.destroy()
  }
  this.$nextTick(() => {
    viewerjs = new Viewer(document.getElementById('id'))
  })
}

</script>

3 方案完善

上述代码示例有个不完善的地方。点击一次图片集合,viewerjs就初始化一次,但对于重复点击同一个图片集合,不应该执行销毁和初始化流程,众所周知,销毁对象、创建对象是一项非常消耗性能的操作,也容易造成内存泄漏。因此对代码示例稍作完善,增加一个lastInitViewerjsID变量,用于记录上一次初始化的图片集合div的id是多少。执行initViewerjs时,先判断触发本次点击事件的图片集合id和上一次初始化的图片集合id是否为同一个,如果为同一个则不执行后续的销毁、初始化流程。

<template>
  <div id="id" @click.capture="initViewerjs(id)">
    <ul id="images">
      <li><img src="picture-1.jpg" alt="Picture 1"></li>
      <li><img src="picture-2.jpg" alt="Picture 2"></li>
      <li><img src="picture-3.jpg" alt="Picture 3"></li>
    </ul>
  </div>
</template>

<script>
import 'viewerjs/dist/viewer.css';
import Viewer from 'viewerjs';

let viewerjs = null
let lastInitViewerjsID = ''
initViewerjs(id) {
  if (id === lastInitViewerjsID ) {
    return
  }
  if (viewerjs !== null) {
    viewerjs.destroy()
  }
  this.$nextTick(() => {
    viewerjs = new Viewer(document.getElementById('id'))
  })
}

</script>

 

参考:

编辑于 2024-11-08 21:35
目录