execCommand() 现在已过时,有什么替代方法?

IT技术 javascript html css execcommand
2021-02-22 06:04:34

我打算使用Document.execCommand()方法和contenteditable属性来构建我的自定义 WYSIWYG 编辑器。但是当我查看 的文档Document.execCommand(),我发现它现在已经过时了。它的现代(或现存)替代品是什么?

4个回答

我为我平台的 XML (HTML5 + XHTML) 编辑目的创建了 Rich Editor。我不会说它document.execCommand()完全死了,因为它的某些部分仍然可以正常工作。不幸的是,对我来说,主要问题是浏览器使用许多不同的代码来生成那些盲人或几乎盲人使用的屏幕阅读器无法识别的样式

此外,我不得不克服的最昂贵的时间错误是 Gecko/Presto 错误,其中视觉和技术选择(为什么它们不是一回事,别问我)会导致部分 DOM 被更改,用户不打算这样做,这归结为每个字符的像素数很低,因此如果 Rich Editor不支持视觉选择,用户会很快走开。这需要四个月才能征服,而且还有其他错误。

最终,这是一项艰巨但可以实现的努力,但如果您打算像我一样构建 HTML/XML 编辑器,您应该计划至少六个月,如果您计划不仅正确地完成它,但对其进行测试到讨厌蛋糕的地步让有人过来指出另一个错误。

你的主要焦点JavaScript的英明应在以下方面:

代替使用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 个字符,并将文件请求(压缩后的有效带宽)减少了一个完整的第三。以下是成功的关键部分:

  1. anchorNodefocusNode可以根据你选择从左或从右到左切换。因为我找不到任何理由来说明为什么这很重要(对于我的平台),所以我将an对象 (for anchorNode) 放在左侧,将fn对象 (for focusNode) 始终放在右侧。

  2. 我使用 ~1,700 个字符解决了 Gecko/Presto 问题;您可以先在网站上找到它(访问具有 Rich 表单的页面)。

  3. 要通过大量的交汇处解决选择的问题<s><sub><sup><u>等(必须测试既简单又令人费解疯狂的例子)最后我用window.getSelection().getRangeAt(0).commonAncestorContainercloneNode,然后才处理剥离什么的选择是不包括在内。然后我只是用来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,并跟踪更改的每次迭代,因此它仍然是一个庞大的项目。对于我的平台,现在没有必要,尽管我想涵盖这一点,因为有些人在评论中提到了它。

所以基本上我应该得到当前的选择并确定我是否需要用span-tag包围它(例如设置font-weighttext-decoration)或例如分割跨度(通过确定任何交叉点并可能关闭甚至删除它们),对吧?另一种解决方案可能是将每个字母包装在一个span-tag 中,但我怀疑随之而来的性能开销会很糟糕——尤其是在较大的文本上......
2021-04-29 06:04:34
@Igor 我的网络平台仍然使用原始的 Rich Editor(您可以通过评论在博客线程页面上预览,除非需要,否则不会加载,按需 JavaScript)。contentEditable属性有效。至于处理复杂的嵌套,有两件事要做:1. 设置最大复杂性的策略,超过时指示用户使用 XML 编辑器;2. 确定最大阈值以使您的项目发布现实。如果你决定在复杂性上疯狂模仿 LibreOffice 的行为;我认为它目前是处理这种复杂性的“标准”。
2021-04-29 06:04:34
@ChuanqiSun 我目前最好的想法是跟踪具有data-edit或类似非侵入性 HTML/XML 属性的更改,并根据它在已编辑内容和/或先前元素之间的相对位置分配一个值。撤消/重做是有序执行,因此您只需在 JavaScript/CSS 属性选择器上向前或向后迭代。由于我正在慢慢地重写我的 Rich Editor,我还没有达到那个点。但是,我相信如果执行得当,您可能会看到大约 800-1,600 字节的 JavaScript
2021-04-30 06:04:34
@Igor我已经更新了我的回答虽然没有,也不能使用span元件以实现风格。如果您需要对句子的一部分进行强烈的措辞,则应<strong>在示例中使用,以便屏幕阅读器理解并为盲人和视力不好的人强烈回读。<span>元素仍然有它的地方适当地使用,还有其他类型的元素时。就性能而言,真正的问题是处理高度嵌套的“样式”(u在 的中间或侧面添加或删除<em><strong><u>example</u></strong></em>)或处理双重嵌套。
2021-05-13 06:04:34
啊——谢谢!所以我应该更喜欢最精确的文本,例如ustrong等等span我的意思是 .. 屏幕阅读器,如 JAWS,会aria根据我在开发应用程序时记得的内容来解释-attributes,这些属性也必须由此类程序读取。是的..嵌套才是真正的麻烦所在..所以我想我不应该使用它们contentEditable吗?
2021-05-15 06:04:34

看起来替代方案是 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() 访问剪贴板。

编辑:如评论以及上面引用的文本中所述,这仅满足要求的一个子集(剪贴板访问)。

您如何使用剪贴板 API 加粗文本、撤消/重做更改等?这仅满足 execCommand 功能的一个非常有限的子集。
2021-05-02 06:04:34

参考文档说,作为警告。

预计未来这两个规范都将被Content EditableInput Events取代

就像每个预测一样,等待确定。