分离与继承的思想实现图片上传后的预览功能:

本文要介绍的是网页中常见的图片上传后直接在页面生成小图预览的实现思路,考虑到该功能有一定的适用性,于是把相关的逻辑封装成了一个ImageUploadView组件,实际使用效果可查看下一段的git效果图。在实现这个组件的过程中,有用到前面几篇博客介绍的相关内容,比如继承库class.js,任意组件的事件管理库eventBase.js,同时包含进了自己对职责分离,表现与行为分离这两方面的一些思考,欢迎阅读与交流。

演示效果:

分离与继承的思想实现图片上传后的预览功能:

注:由于演示的代码都是静态的,所以文件上传的组件是用setTimeout模拟的,不过它的调用方式跟我自己在实际工作中用上传组件完全相同,所以演示效果的代码实现完全符合真实的功能需求。

按照我以前博客的思路,先来介绍下这个上传预览功能的需求。

1. 需求分析

根据前面的演示效果图,分析需求如下:

1)初始时上传区域只显示一个可点击上传的按钮,当点击该按钮后,将上传成功的图片显示在后面的预览区域

2)上传的图片添加到预览区域以后,可以通过删除按钮来移除

3)当已上传的图片总数达到一定限制之后,比如演示中已上传的限制为4,就把上传按钮给移除掉;

4)当已上传的图片总数达到一定限制之时,如果通过删除操作移除了某张图片,还得再把上传按钮给显示出来。

以上需求是看的见的,根据经验,还可以分析得出的需求如下:

1)如果页面是编辑状态,也就是从数据库中查询出来的状态,只要图片列表不为空,初始时还得把图片显示出来;而且还要根据查出来的图片列表的长度跟上传限制去控制上传按钮是否显示;

2)如果当前页面是一种只能看不能改的状态,那么在初始时一定要把上传按钮和删除按钮移除掉。

需求分析完毕,接下来说明一下我的实现思路。

2. 实现思路

由于这是个表单页面,所以图片上传完以后如果要提交到后台,肯定得需要一个文本域,所以我在做静态页面的时候就把这个文本域考虑进去了,当上传完新的图片以及删除了图片之后都得去修改这个文本域的值。当时做静态页时这部分的结构如下:

<div> <label>法人身份证电子版</label> <div> <input type="hidden"> <ul> <li><a href="javascript:;" title="点击上传">+</a> </li> </ul> <p> 请确保图片清晰,文字可辨 <a href="#" title="查看示例"><i></i> 查看示例</a> </p> </div> </div>

从这个结构还可以看出,我把整个上传区域都放在一个ul里面,然后把ul的第一个li作为上传按钮来使用。为了完成这个功能,我们主要的任务是:上传及上传后的回调,新增或删除图片预览以及文本域值的管理。从这一点,结合职责分离的思想,这个功能至少需要三个组件,一个负责文件上传,一个负责图片预览的管理,一个负责文本域值的管理。千万不能把这三个功能,两两或者全部都封装在一起,那样的话功能耦合太强,写出来的组件可扩展性可重用性不高。如果这三个组件之间需要交互,我们只要借助回调函数或者发布-订阅模式定义它们给外部调用的接口即可。

不过文本域值的管理本身就很简单,写不写成组件都关系不大,但是至少函数级别的封装是得有的;文件上传组件虽然不是本文的重点,但是网上有很多现成的开源插件,比如webuploader,不管是直接用还是做二次封装都可以应用进来;图片预览的功能是本文的核心内容,ImageUploadView这个组件就是对它的封装,从需求来看,这个组件有语义的实例方法无非就是三个,分别是render, append, delItem,其中render用来在初始化完成之后显示初始的预览列表,append用来在上传成功后添加新的图片预览,delItem用来删除已有的图片预览,按照这个基本思路,我们只需要再结合需求和组件开发的经验为它设计好options和事件即可。

从前面的需求我们发现,这个ImageUploadView组件的render会受到页面状态的影响,当页面为查看模式时,这个组件不能做上传和删除的操作,所以可以考虑给它加一个readonly的option。同时它的上传和删除操作还会影响到上传按钮的UI逻辑,这个跟上传限制有关系,为了灵活性,也得把上传限制作为一个option。从前一段提到的三个实例方法来说,按照自己以前定义事件的经验,一般一个实例方法会定义一对事件,就像bootstrap的插件的做法一样,比如render方法,可以定义一个render.before,这个事件在render的主要逻辑执行前触发,如果外部监听器调用了这个事件的preventDefault()方法,那么render的主要逻辑都不会执行;还有一个render.after事件,这个事件在render的主要逻辑执行后触发。这种成对定义事件的好处是,既给外部提供扩展组件功能的方法,又能增加组件默认行为的管理。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wgyzsy.html