Vditor 动态修改图片大小的个人解决方案

本贴最后更新于 996 天前,其中的信息可能已经时移俗易

对于 Vditor 动态修改图片大小的个人解决方案

为什么要解决这个问题?

最近在准备毕业设计,想做个交流平台,在找 MD 编辑器的时候有幸找到 Vditor 能够边渲染边编辑的优秀编辑器。但是在处理图片时发现它不能让用户自定义图片的大小,所以对此寻找解决方案。

可惜的是,想白嫖的方案但没有搜到,在该论坛也发现过有这个需求的开发者,作者也提供了个比较简单的方案,就是通过 css 控制。但是这个并不满足我自定义的需求。

偶然发现点击图片的框框

在点击图片时,我偶然发现有个输入框提供用户进行自定义修改地址等信息。于是我突发奇想往上面添加个修改高度宽度的输入框不就 OK 了嘛~

image.png

虽然有点粗糙,【但是本人审美感觉过得去,hhhh】。

框框加上去了,那么如何自定义高度宽度呢?我尝试了各种方式,比如正则匹配将属性然后附加到图片上,又或者直接添加元素。【在测试过程中,MD 的隐藏更新给了我很大的麻烦,但是后面是发现自己脑子 CPU 烧坏了】

image.png

通过记录 md 的同时,修改 HTMLdisplay 将高度宽度隐藏起来,那么用户在修改高度和宽度的同时编辑文字不会收到数据的影响。【至于为什么要记录 md,这是因为我后端保存的是 markdown 的语法而不是 html……而且不太想改后端,这很尴尬……不然其实这功能的实现还是比较简单的。】

至于代码我这里直接贴上,希望可以给有想法的人参考下。

let currentImgCount = 0; // 监听点击事件,监听点击 img document.onclick = function (event) { if (event?.target?.nodeName === 'IMG') { // 追加输入框 let target: HTMLAnchorElement = event.target as HTMLAnchorElement; let vditorPanel = document.getElementsByClassName('vditor-panel vditor-panel--none'); let imgPanel = vditorPanel[0]; // 创建 span let heightAndWidthSpan = document.createElement('span'); heightAndWidthSpan.setAttribute('class', 'vditor-tooltipped vditor-tooltipped__n'); heightAndWidthSpan.setAttribute('aria-label', '宽x高'); // 创建 input let heightAndWidthInput = document.createElement('input'); heightAndWidthInput.setAttribute('class', 'vditor-input'); heightAndWidthInput.setAttribute('placeholder', '输入宽x高'); // 判断是否有过值 let imgId = target.getAttribute('id'); if (imgId) { let oldPosition = document.getElementById(imgId.replace('img', 'position')); if (oldPosition) { let oldInnerText = oldPosition.innerText, oldInnerStr = oldInnerText.replace('{{', '').replace('}}', ''); let oldInnerArr = oldInnerStr.split(','), height = oldInnerArr[0], width = oldInnerArr[1]; heightAndWidthInput.value = `${height}x${width}`.trim(); } } // span 追加 input heightAndWidthSpan.appendChild(heightAndWidthInput); // imgPanel 追加 heightAndWidthSpan imgPanel.appendChild(heightAndWidthSpan); // 回车更新 heightAndWidthInput.onchange = () => { let val = heightAndWidthInput.value; let hw = val.split('x'); let tempHeight = Number(hw[0]), tempWidth = Number(hw[1]); if (tempHeight <= 0 || tempWidth <= 0) { toast.error('提示提示', '长度和宽度最少要大于0哦~', 1000) } else if (target) { let parentEle = target.parentElement; target.style.height = `${tempHeight}px`; target.style.width = `${tempWidth}px`; let alt = target.getAttribute('alt'), positionId = `position-${alt}-${currentImgCount}`; target.setAttribute('id', `img-${alt}-${currentImgCount}`); if (parentEle) { let positionSpan = document.getElementById(positionId); if (positionSpan) { parentEle.removeChild(positionSpan); } parentEle.innerHTML += `<span id="${positionId}" style="display: none;">{{${tempHeight}, ${tempWidth}}}</span>`; // 更新值 md.value = editor.getValue(); html.value = editor.getHTML(); // 更新计数器 currentImgCount++; } } } } }

数据的渲染怎么办?

这里其实是我自己埋下的坑,因为我后端保存的是 markdown 语法【因为本人觉得 markdown 语法存储的字符串比 html 少。

因为我们存储时 markdownimg 跟随有 {{height, width}} 的数据,那么我们拿回来时,再通过正则匹配筛选带有 {{height, width}}img 标签。而后再更改高度、宽度,最后重新赋值 innertHTML 就 OK 了。

效果就不用展示啦~这里就直接贴代码了。

// 更新图片大小的细节 let imgs = document.getElementsByTagName('img'); let pattern = /{{\d+,(\s)*\d+}}/; if (imgs && imgs.length > 0) { for (let img of imgs) { let imgParentEle = img.parentElement; if (imgParentEle) { let innerHtml = imgParentEle.innerHTML if (pattern.test(innerHtml)) { let matchs = innerHtml.match(pattern); if (matchs) { for (let match of matchs) { if (match.trim() !== '') { // 获取高度进行筛选过滤 let matchStr = match.replace('{{', '').replace('}}', ''), matchArr = matchStr.split(','); let height = matchArr[0], width = matchArr[1]; // 赋值 style img.style.height = `${height}px`; img.style.width = `${width}px`; // 清除 {{number, number}} imgParentEle.innerHTML = imgParentEle.innerHTML.replace(match, ''); } } } } } } }

希望对有这需求的人有帮助~

  • Vditor

    Vditor 是一款浏览器端的 Markdown 编辑器,支持所见即所得、即时渲染(类似 Typora)和分屏预览模式。它使用 TypeScript 实现,支持原生 JavaScript、Vue、React 和 Angular。

    372 引用 • 1857 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • huangtao

    最后有解决办法吗?支持针对某个图片单独设置尺寸,并且导出 md 和 html 也是带尺寸属性的。

  • huangtao

    我觉得可以修改宽度就行,宽高度同时修改有可能使图标比例失调, 希望官方能考虑加上修改图片宽度的功能