Rails项目中Summernote选图后自动插入,如何改为点击插入按钮触发?
解决Summernote选择图片后自动插入的问题
我明白你遇到的问题——默认情况下Summernote选择图片后会直接上传插入,跳过了「确认插入」的步骤,确实不符合预期的交互逻辑。我们可以通过自定义图片上传弹窗和按钮逻辑来解决这个问题,具体修改如下:
步骤1:替换默认图片按钮为自定义按钮
首先在Summernote初始化配置中,把工具栏里的默认picture按钮替换成我们自己的customPicture按钮,这样就能完全接管图片上传的流程:
$(document).ready(function($) { $(".summernote_custom").summernote({ height: 200, styleTags: ['p', 'h1', 'h2'], toolbar: [ ['style', ['bold', 'italic', 'underline', 'clear']], ['para', ['ul', 'ol', 'paragraph','style']], ['fontname', ['fontname']], ['fontsize',['fontsize']], ['insert', ['customPicture','link']] // 替换默认picture为自定义按钮 ], dialogsInBody: true, buttons: { customPicture: function(context) { var ui = $.summernote.ui; // 创建自定义图片按钮 var button = ui.button({ contents: '<i class="note-icon-picture"/>', tooltip: '插入图片', click: function() { // 点击按钮时打开自定义弹窗 openCustomImageDialog(context); } }); return button.render(); } } }); });
步骤2:编写自定义图片上传弹窗
接下来创建一个包含「文件选择、预览、确认插入」的自定义弹窗,让用户可以先预览图片,再手动触发上传插入:
function openCustomImageDialog(context) { // 构建Bootstrap模态框(如果项目没用到Bootstrap,可自行替换为原生弹窗) var $dialog = $('<div class="modal fade" tabindex="-1" role="dialog">' + '<div class="modal-dialog" role="document">' + '<div class="modal-content">' + '<div class="modal-header">' + '<h5 class="modal-title">插入图片</h5>' + '<button type="button" class="close" data-dismiss="modal" aria-label="Close">' + '<span aria-hidden="true">×</span>' + '</button>' + '</div>' + '<div class="modal-body">' + '<input type="file" id="customImageInput" accept="image/*" style="margin-bottom:10px;">' + '<img id="imagePreview" src="#" alt="预览图片" style="max-width:100%;display:none;">' + '</div>' + '<div class="modal-footer">' + '<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>' + '<button type="button" class="btn btn-primary" id="uploadAndInsertBtn">插入图片</button>' + '</div>' + '</div>' + '</div>' + '</div>'); // 文件选择后显示预览 $dialog.find('#customImageInput').on('change', function(e) { var file = e.target.files[0]; if (file) { var reader = new FileReader(); reader.onload = function(event) { $dialog.find('#imagePreview').attr('src', event.target.result).show(); }; reader.readAsDataURL(file); } }); // 点击「插入图片」按钮时触发上传和插入 $dialog.find('#uploadAndInsertBtn').on('click', function() { var file = $dialog.find('#customImageInput')[0].files[0]; if (!file) { alert('请先选择图片文件'); return; } // 调用上传函数,成功后插入图片 uploadImage(file, context.invoke('editor'), function(imageUrl) { context.invoke('editor.insertImage', imageUrl, function($image) { $image.css('width', '100%'); $image.attr('data-filename', 'retriever'); }); $dialog.modal('hide'); // 关闭弹窗 }); }); // 显示弹窗 $dialog.modal('show'); // 弹窗关闭后清理DOM元素 $dialog.on('hidden.bs.modal', function() { $(this).remove(); }); }
步骤3:修改上传函数支持回调
最后调整uploadImage函数,添加回调参数,确保只有上传成功后才会执行图片插入操作:
function uploadImage(image, editor, successCallback) { var data = new FormData(); data.append("image", image); data.append("name", "resource"); $.ajax({ data: data, type: "POST", url: "#{ajax_upload_doctor_attachments_path}", cache: false, contentType: false, processData: false, success: function(data) { var imageUrl = "#{HOST}" + data.url; if (successCallback) { successCallback(imageUrl); // 上传成功后执行插入回调 } }, error: function(data) { console.log(data); alert('图片上传失败,请重试'); } }); }
原理说明
通过替换默认的图片按钮,我们完全绕过了Summernote自带的自动上传插入逻辑,转而使用自定义的交互流程:用户点击图片按钮→选择文件预览→手动确认插入→上传图片并插入到编辑器。这样就实现了「等待点击插入按钮再触发上传」的需求。
如果你的项目没有使用Bootstrap,可以把弹窗部分改成原生JavaScript的弹窗(比如自定义div的显示隐藏),核心逻辑保持一致即可。
内容的提问来源于stack exchange,提问作者Muhammad Faisal Iqbal
相关产品推荐
相关产品推荐

