我打算使用Document.execCommand()
方法和contenteditable
属性来构建我的自定义 WYSIWYG 编辑器。但是当我查看 的文档时Document.execCommand()
,我发现它现在已经过时了。它的现代(或现存)替代品是什么?
execCommand() 现在已过时,有什么替代方法?
我为我平台的 XML (HTML5 + XHTML) 编辑目的创建了 Rich Editor。我不会说它document.execCommand()
完全死了,因为它的某些部分仍然可以正常工作。不幸的是,对我来说,主要问题是浏览器使用许多不同的代码来生成那些盲人或几乎盲人使用的屏幕阅读器无法识别的样式。
此外,我不得不克服的最昂贵的时间错误是 Gecko/Presto 错误,其中视觉和技术选择(为什么它们不是一回事,别问我)会导致部分 DOM 被更改,用户不打算这样做,这归结为每个字符的像素数很低,因此如果 Rich Editor不支持视觉选择,用户会很快走开。这需要四个月才能征服,而且还有其他错误。
最终,这是一项艰巨但可以实现的努力,但如果您打算像我一样构建 HTML/XML 编辑器,您应该计划至少六个月,如果您计划不仅正确地完成它,但对其进行测试到讨厌蛋糕的地步让有人过来指出另一个错误。
你的主要焦点JavaScript的英明应在以下方面:
window.createRange()
window.createRange().surroundContents()
Node.cloneNode()
window.getSelection()
window.getSelection().getRangeAt(0).commonAncestorContainer
appendChild
insertBefore
insertBefore
+nextSibling
replaceChild
代替使用execCommand()
不同浏览器生成的不一致代码(通常设置内联样式,如果不完全否定它,这会使您网站的 CSS 复杂化),您应该坚持使用以下元素,您不仅可以控制这些元素,而且与屏幕阅读器兼容:
em
强调(或“斜体”,<i>
已弃用)。strong
对于强烈阅读的文本(或“粗体”,<b>
已弃用)。u
对于下划线(确保您的锚的样式与 u 元素区分开来;u
可能会被视为“已弃用”,尽管我会在未来十年左右修复标准时将其反转,请适当使用它)。sub
用于垂直显示低于正常文本的子行文本。sup
用于显示垂直高于普通文本的超行文本。- 千万不能使用
<span>
元素专门添加这些样式,屏幕阅读器将无法理解或显示错误行为; 如果使用得当,它仍然是一个有效的通用内联元素。
我实际上一直打算修改我的 Rich Editor(它已经打了补丁,但尚未正确重写),尽管欢迎您在我的个人资料中链接的站点的博客页面上加载源代码时查看源代码。最初的项目花了我 11 个月,但根据我现在的经验,我认为我需要大约三到四个月。如果你是认真的,我强烈建议你远离框架和库。“但是……但是,它们让生活更轻松!” ...直到您想使用新版本并且必须重写整个项目。第一次使用纯 JavaScript,否定无意义的维护。祝你好运!
2021-09-24:我从大约一年前开始恢复 Rich Editor II 的工作,并设法将更改样式的代码从 100,515 个字符转换为 ~6,000 个字符,并将文件请求(压缩后的有效带宽)减少了一个完整的第三。以下是成功的关键部分:
该
anchorNode
和focusNode
可以根据你选择从左或从右到左切换。因为我找不到任何理由来说明为什么这很重要(对于我的平台),所以我将an
对象 (foranchorNode
) 放在左侧,将fn
对象 (forfocusNode
) 始终放在右侧。我使用 ~1,700 个字符解决了 Gecko/Presto 问题;您可以先在网站上找到它(访问具有 Rich 表单的页面)。
要通过大量的交汇处解决选择的问题
<s>
,<sub>
,<sup>
,<u>
等(必须测试既简单又令人费解疯狂的例子)最后我用window.getSelection().getRangeAt(0).commonAncestorContainer
用cloneNode
,然后才处理该剥离什么的选择是不包括在内。然后我只是用来window.getSelection().deleteFromDocument();
删除选择并将其替换为新的样式元素,document.createElement
这样我就可以轻松地appendChild
将选择插入到window.getSelection().getRangeAt(0).insertNode(id_('editor_rich_text').firstChild);
.
Gecko 浏览器(例如 Waterfox、Pale Moon 和现已完全销毁的 Firefox)允许您选择多个文本实例。为此,只需按住Control
键即可创建额外的选择。由于它并没有真正以任何有意义的方式提供帮助(而且这些东西已经足够复杂了)我此时并没有特意支持它。
我将在今天或本周末(截至本文编辑)更新我的平台以反映新的变化。由于 Gecko 浏览器的许多问题,我保留了很多旧代码。我已经扩展了功能并解决了许多错误,并且不必求助于任何黑客,并且像往常一样没有车库(框架或库)。
2021 年 9 月 26 日:对于那些对重做/撤消功能感兴趣的人,您将不得不求助于基本上保留您正在编辑的 DOM 部分的文本版本。当然,可能还有其他方法来实现它,尽管这些方法会非常复杂。您基本上只需使用编辑器父元素的副本,.cloneNode
然后在内存中使用类似while (e.firstChild) {xml += new XMLSerializer().serializeToString(e.firstChild);}
. 由于您将其存储为文本,因此不会像 DOM 那样具有巨大的内存影响。您实际上将在编辑器中替换整个 DOM,并跟踪更改的每次迭代,因此它仍然是一个庞大的项目。对于我的平台,现在没有必要,尽管我想涵盖这一点,因为有些人在评论中提到了它。
看起来替代方案是 Input Events Level 2。
虽然创建一个自制的 WYSIWYG 编辑器很诱人,但我个人会坚持使用 execCommand 直到新标准到来。因为我们都会自己编写一个完整的编辑器,而不是重复使用现有的工作解决方案。
替代方法document.execCommand()
是剪贴板 API,通过navigator.clipboard
. 根据 MDN 网络文档(https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API):
此 API 旨在取代使用 document.execCommand() 访问剪贴板。
编辑:如评论以及上面引用的文本中所述,这仅满足要求的一个子集(剪贴板访问)。