基于bootstrap-wysiwyg与ajaxFileUpload实现图片上传与实时预览

作者:清欢时间:2026-10-30 07:36:12浏览:277

本文介绍如何在bootstrap-wysiwyg编辑器中集成ajaxFileUpload插件,解决原生FileApi仅生成Base64字符串的问题。通过重写insertFiles函数并修改监听器,实现图片上传至服务器后获取真实URL并实时插入编辑器的功能,确保存储路径的有效性与用户体验。

插件选型与需求分析

近期项目要求实现一个前端文本编辑框,并具备图片上传后实时查看的功能。对比市面上几款插件后,首先排除了百度UEditor,因其框架过于庞大,引入过多文件不符合精简需求;其次考虑jQuery的easyUI,虽个人版免费,但鉴于项目为公司业务,使用商业版框架存在合规风险。考虑到项目前端主要基于Bootstrap构建,最终选定bootstrap-wysiwyg插件,该插件精简、轻量且具备较强的扩展性。

引入bootstrap-wysiwyg并实现文本编辑功能较为便捷,但注意到其图片上传机制基于FileApi。尽管FileApi实现的无刷新预览体验良好,但在实际存入数据库时,通常希望存储图片在服务器的静态路径,而非字符串化的Base64数据。因此,需要对bootstrap-wysiwyg(以下简称WY)进行适当改写以满足需求。

源码分析与功能改写

首先观察页面上的图片控件,忽略其他控件,通过查阅源码可以发现如下结构:


<div class="btn-group">
 <a class="btn" title="Insert picture (or just drag & drop)" id="pictureBtn">
 <i class="icon-picture"></i></a>
  <input type="file" data-role="magic-overlay" 
   data-target="#pictureBtn"
  data-edit="insertImage" />
</div>

对此进行说明:data-role和data-target属性是Bootstrap中预定义的事件,在此处主要涉及布局相关逻辑,无需过多关注。关键点在于第三个属性data-edit,Bootstrap本身并未定义此事件。观察bootstrap-wysiwyg.js源码,可以发现相关处理代码:


toolbar.find('input[type=file][data-' + options.commandRole + ']')
   .change( ...
   ...
commandRole : 'edit',

由此可见,该属性主要是为了方便选择器操作而实现,相当于为图片按钮添加了监听器事件。

接下来研究WY图片预览的实现机制。如上述代码所示,监听器捕获fileInput的change事件后做出响应,并调用insertFiles函数。


restoreSelection();
if (this.type === 'file' && this.files && this.files.length > 0) {
 insertFiles(this.files);
}
saveSelection();
his.value = '';

定位到insertFiles函数的定义。


insertFiles = function (files) {
  editor.focus();
  $.each(files, function (idx, fileInfo) {
   if (/^image\//.test(fileInfo.type)) {
   $.when(readFileIntoDataUrl(fileInfo)).done(function (dataUrl) {
    execCommand('insertimage', dataUrl);
   }).fail(function (e) {
    options.fileUploadError("file-reader", e);
   });
   } else {
   options.fileUploadError("unsupported-file-type", fileInfo.type);
   }
  });
  }

注意到该函数使用了jQuery的$.Deferred()方法,首先调用readFileIntoDataUrl方法,成功后通过自封装的execCommand方法将图片输出到文本框。此时插入的图片实际上是一个<img>标签,其src属性为字符串表示的图片数据。因此,我们的目标是在监听器触发后,先执行文件上传,获取图片的src链接,再将链接传递给后续的execCommand方法。

由于笔者对Deferred对象尚不熟悉,故采用更为常规的callback回调模式进行实现。

观察ajaxFileUpload的调用方式:


$.ajaxFileUpload({
  url : ...,
  secureurl : false,
  fileElementId : ...,
  dataType : "json",
  success : function(obj) {
   ...
  },
  error : function() {
   ...
  }
  });

该调用有两个必选属性:url和fileElementId。为了保持依赖关系的正确性,直接重写ajaxFileUpload插件并不可取。但由于WY控件是通过监听器实现的,通过函数直接传递参数并不现实,因此需要为输入框定义特定属性以达到目的。

在fileInput元素中添加以下属性:


<input type="file" id="pictureInput" name="picture"
   data-role="magic-overlay" data-target="#pictureBtn"
   data-edit="insertImage" action="..." />

其中id用于对应fileElementId,name属性也是必须的,主要用于后台取值时的标识,action属性指定图片需要提交到的服务器URL。

实现图片上传与实时预览

在bootstrap-wysiwyg.js中定义一个名为uploadFileToServer的函数,其格式如下:


var uploadFileToServer = function(id, action, callback) {
 $.ajaxFileUpload({
  url : action,
  secureurl : false,
  fileElementId : id,
  dataType : 'json',
  success : function(obj) {
  if (obj.status) {
   callback(obj.imgsrc);
  } else
   options.fileUploadError("server-internal-exception",
    obj.message);
  },
  error : function() {
  options.fileUploadErroe("upload-failure", "");
  }
 });

将insertFiles方法改写如下:


insertFiles = function(files, id, action) {
  editor.focus();
  $.each(files, function(idx, fileInfo) {
  if (/^image\//.test(fileInfo.type)) {
   /*
   * $.when(readFileIntoDataUrl(fileInfo)).done(function(dataUrl) {
   * execCommand('insertimage', dataUrl); }).fail(function(e) {
   * options.fileUploadError("file-reader", e); });
   */
   uploadFileToServer(id, action, function(src) {
   execCommand('insertimage', src);
   });
  } else {
   options.fileUploadError("unsupported-file-type",
    fileInfo.type);
  }
  });

同时对监听器进行相应修改,以便获取必要的属性参数。


toolbar.find('input[type=file][data-' + options.commandRole + ']')
  .change(
   function() {
    restoreSelection();
    if (this.type === 'file' && this.files
     && this.files.length > 0) {
     insertFiles(this.files, $(this).attr('id'),
      $(this).attr('action'));
    }
    saveSelection();
    this.value = '';
    });

主要增加了两个参数位置以支持上传逻辑。

至此,改写工作完成。请注意,为确保功能正确执行,请在控件初始化之前引用ajaxFileUpload.js文件。

如果读者希望深入学习,可以点击相关链接进行学习,另附三个精彩专题供参考:

Bootstrap学习教程

Bootstrap实战教程

Bootstrap插件使用教程

以上为本文全部内容,希望对读者的学习有所帮助,也欢迎大家多多支持本站。

作者最新文章