trix
每天写作的丰富文本编辑器
在您的Web应用程序中撰写精美格式的文本。 trix是Wysiwyg的编辑器,用于编写消息,评论,文章和列表 – 简单的文档大多数Web应用程序都是由。它具有复杂的文档模型,对嵌入式附件的支持,并输出简短和一致的HTML。
trix是一个来自37 signals的开源项目,Ruby on Rails的创建者。成千上万的人信任我们的文字,我们建立了trix ,以赋予他们最好的编辑体验。参见Basecamp 3中的trix 。
设计不同
当trix于2014年设计时,大多数Wysiwyg编辑都是由Microsoft设计的HTML的可满足和execcommand API的包装纸,该版本是由Microsoft设计的,旨在支持Internet Explorer 5.5中网页的实时编辑,并最终对其他浏览器进行反向工程和副本。
由于这些API尚未完全指定或记录,并且由于Wysiwyg HTML编辑器的范围很大,因此每个浏览器的实现都有其自己的错误和怪癖集,并且JavaScript开发人员可以解决不一致之处。
trix通过将可满足的设备视为I/O设备来避开这些不一致之处:当输入进入编辑器时, trix将输入转换为其内部文档模型的编辑操作,然后将文档重新呈现为编辑器。这trix完全控制每次击键之后发生的事情,并避免使用ExecCommand的需求。
这是所有现代生产,Wysiwyg编辑现在采用的方法。
建立在网络标准上
trix支持所有常绿,自我更新的桌面和移动浏览器。
trix具有既定的Web标准,尤其是自定义元素,元素内部,突变观察者和承诺。
入门
trix以ESM和UMD格式捆绑在一起,并与任何资产包装系统一起使用。
从trix开始的最简单方法是从页面的<头>中的NPM CDN中包括它:
trix.css\”>
<script type=\”text/javascript\” src=\”https://un***pkg.com/trix@2.0.8/dist/ trix .umd.min.js\”></script>
</head>\”>
< head > … < link rel =\" stylesheet \" type =\" text/css \" href =\" https://un***pkg.com/trix@2.0.8/dist/ trix .css \" > < script type =\" text/javascript \" src =\" https://un***pkg.com/trix@2.0.8/dist/ trix .umd.min.js \" > </ script > </ head >
trix .CSS包括trix工具栏,编辑器和附件的默认样式。如果您想自己定义这些样式,请跳过此文件。
另外,您可以安装NPM软件包并将其导入您的应用程序:
trix \”
document.addEventListener(\” trix -before-initialize\”, () => {
// Change trix .config if you need
})\”>
import trix from \" trix \" document . addEventListener ( \" trix -before-initialize\" , ( ) => { // Change trix .config if you need } )
创建编辑器
将空的< trix -editor> </ trix -editor>标记放在页面上。 trix将在编辑器之前自动插入一个单独的< trix -toolbar>。
就像html <textarea>一样,< trix -editor>接受自动对焦和占位符属性。与<textarea>不同,< trix -editor>自动垂直扩展以适合其内容。
创建工具栏
trix会自动为您创建工具栏,并在< trix -editor>元素之前将其附加。如果您想将工具栏放在其他地方,则可以使用工具栏属性:
trix -toolbar>
<div class=\”more-stuff-inbetween\”></div>
< trix -editor toolbar=\”my_toolbar\” input=\”my_input\”></ trix -editor>
</main>\”>
< main > < trix -toolbar id =\" my_toolbar \" > </ trix -toolbar > < div class =\" more-stuff-inbetween \" > </ div > < trix -editor toolbar =\" my_toolbar \" input =\" my_input \" > </ trix -editor > </ main >
要更改工具栏而无需修改trix ,您可以覆盖trix .config.toolbar.getDefaulthtml()函数。默认工具栏html在config/toolbar.js中。 trix使用数据属性来确定如何响应工具栏按钮。
切换属性
使用Data trix -attribute =“ <属性名称>”,您可以在当前选择中添加一个属性。例如,要将粗体样式应用于所选文本的按钮是:
trix -key=\”b\”></button>\”>
< button type =\" button \" class =\" bold \" data- trix -attribute =\" bold \" data- trix -key =\" b \" > </ button >
trix将确定选择了一系列文本,并将应用在trix .config.textattributes中定义的格式(在config/text_attributes.js中找到)。
data trix -key =“ b”告诉trix ,当您使用meta + b时,应应用此属性。
如果属性是在trix .config.blockattributes中定义的, trix将将属性应用于文本的当前块。
< button type =\" button \" class =\" quote \" data- trix -attribute =\" quote \" > </ button >
单击报价按钮切换是否应使用<blockQuote>渲染块。
与元素内部集成
trix将根据浏览器对元素内部的支持,将< trix -editor>元素与表单集成在一起。如果需要禁用对ElementInternals的支持,请设置trix .elements。 trix editorelement.formassified = false:
trix \”
trix .elements. trix EditorElement.formAssociated = false\”>
import trix from \" trix \" trix . elements . trix EditorElement . formAssociated = false
调用内部trix动作
内部操作是在控制器/editor_controller.js中定义的,包括:
- 撤消
- 重做
- 关联
- 增加blocklevel
- 降低blocklevel
< button type =\" button \" class =\" block-level decrease \" data- trix -action =\" decreaseBlockLevel \" > </ button >
调用外部自定义操作
如果要在工具栏中添加一个按钮并将其调用外部操作,则可以使用X-将操作名称前缀。例如,如果我想在单击新按钮时打印一个日志语句,我将通过按钮的数据属性设置为数据trix -action =“ x-log”
< button id =\" log-button \" type =\" button \" data- trix -action =\" x-log \" > </ button >
要响应该动作,请聆听trix -action -Action -invoke。事件的目标属性返回对< trix -editor>元素的引用,其InvokingElement属性返回对<button>元素的引用,其ActionName属性返回[data trix -action]属性的值。使用ActionName属性的值来检测调用哪些外部操作。
trix-action-invoke\”, function(event) {
const { target, invokingElement, actionName } = event
if (actionName === \”x-log\”) {
console.log(`Custom ${actionName} invoked from ${invokingElement.id} button on ${target.id} trix -editor`)
}
})\”>
document . addEventListener ( \" trix -action-invoke\" , function ( event ) { const { target , invokingElement , actionName } = event if ( actionName === \"x-log\" ) { console . log ( `Custom ${ actionName } invoked from ${ invokingElement . id } button on ${ target . id } trix -editor` ) } } )
与形式集成
要提交带有表单的< trix -editor>的内容,请首先在表单中定义隐藏的输入字段,然后为其分配一个ID。然后在编辑器的输入属性中引用该ID。
trix -editor>
</form>\”>
< form … > < input id =\" x \" type =\" hidden \" name =\" content \" > < trix -editor input =\" x \" > </ trix -editor > </ form >
trix将自动更新隐藏输入字段的值,每个更改为编辑器。
用存储的内容填充
要用存储的内容填充< trix -editor>,请在关联的输入元素的值属性中包含该内容。
trix -editor>
</form>\”>
< form … > < input id =\" x \" value =\" Editor content goes here \" type =\" hidden \" name =\" content \" > < trix -editor input =\" x \" > </ trix -editor > </ form >
始终使用关联的输入元素安全填充编辑器。 trix不会在< trix -editor>…</ trix -editor>标签中加载任何HTML内容。
验证编辑器
开箱即用,< trix -editor>元素支持浏览器的内置约束验证。当使用所需属性渲染时,当编辑器完全空时,编辑器将无效。例如,考虑以下HTML:
trix -editor>\”>
< input id =\" x \" value =\"\" type =\" hidden \" name =\" content \" > < trix -editor input =\" x \" required > </ trix -editor >
由于< trix -editor>元素是[必需的],因此当其值为空时,它是无效的:
trix-editor\”)
editor.validity.valid // => false
editor.validity.valueMissing // => true
editor.matches(\”:valid\”) // => false
editor.matches(\”:invalid\”) // => true
editor.value = \”A value that isn\’t empty\”
editor.validity.valid // => true
editor.validity.valueMissing // => false
editor.matches(\”:valid\”) // => true
editor.matches(\”:invalid\”) // => false\”>
const editor = document . querySelector ( \" trix -editor\" ) editor . validity . valid // => false editor . validity . valueMissing // => true editor . matches ( \":valid\" ) // => false editor . matches ( \":invalid\" ) // => true editor . value = \"A value that isn\'t empty\" editor . validity . valid // => true editor . validity . valueMissing // => false editor . matches ( \":valid\" ) // => true editor . matches ( \":invalid\" ) // => false
除了内置的[必需]属性外,< trix -editor>元素还通过其setCustomVality方法支持自定义验证。例如,考虑以下HTML:
trix -editor>\”>
< input id = \"x\" value = \"\" type = \"hidden\" name = \"content\" > < trix -editor input = \"x\" > </ trix -editor >
可以随时进行自定义验证。例如,在编辑内容更改后触发trix -Change事件后,可以进行验证:
trix-change\”, (event) => {
const editorElement = event.target
const trix Document = editorElement.editor.getDocument()
const isValid = ( trix Document) => {
// determine the validity based on your custom criteria
return true
}
if (isValid( trix Document)) {
editorElement.setCustomValidity(\”\”)
} else {
editorElement.setCustomValidity(\”The document is not valid.\”)
}
}\”>
addEventListener ( \" trix -change\" , ( event ) => { const editorElement = event . target const trix Document = editorElement . editor . getDocument ( ) const isValid = ( trix Document ) => { // determine the validity based on your custom criteria return true } if ( isValid ( trix Document ) ) { editorElement . setCustomValidity ( \"\" ) } else { editorElement . setCustomValidity ( \"The document is not valid.\" ) } }
禁用编辑器
要禁用< trix -editor>,请使用[disabled]属性:
trix -editor>\”>
< trix -editor disabled > </ trix -editor >
禁用的编辑器不是可编辑的,无法接收焦点,并且当提交相关<形式>元素时,其价值将被忽略。
要更改编辑器是否被禁用,请切换[禁用]属性或为.disabled属性分配布尔值:
trix -editor>
<script>
const editor = document.getElementById(\”editor\”)
editor.toggleAttribute(\”disabled\”, false)
editor.disabled = true
</script>\”>
< trix -editor id =\" editor \" disabled > </ trix -editor > < script > const editor = document . getElementById ( \"editor\" ) editor . toggleAttribute ( \"disabled\" , false ) editor . disabled = true </ script >
禁用时,编辑器将匹配:禁用的CSS伪级。
提供一个可访问的名称
像其他表单控件一样,< trix -editor>元素应具有可访问的名称。 < trix -editor>元素与<label>元素集成。它支持与<label>元素集成的两种样式:
- 呈现< trix -editor>元素具有[id]属性,该属性是<label>元素通过其[for]属性的引用:
trix -editor>\”>
< label for =\" editor \" > Editor </ label > < trix -editor id =\" editor \" > </ trix -editor >
- 渲染< trix -editor>元素作为<label>元素的孩子:
trix -toolbar>
<label>
Editor
< trix -editor toolbar=\”editor-toolbar\”></ trix -editor>
</label>\”>
< trix -toolbar id =\" editor-toolbar \" > </ trix -toolbar > < label > Editor < trix -editor toolbar =\" editor-toolbar \" > </ trix -editor > </ label >
警告
将< trix -editor>元素作为<label>元素的孩子呈现时,明确呈现相应的< trix -toolbar>元素<label>元素之外。
除了与<label>元素集成外,< trix -editor>元素支持[aria-label]和[aria-labelledby]属性。
样式格式的内容
为了确保您在保存时看到的是所看到的内容,请使用CSS类名称来示例样式的trix格式化内容。将此类名称应用于您的< trix -editor>元素,并在渲染存储的trix内容以在应用程序中显示时包含元素。
trix -content\”></ trix -editor>\”>
< trix -editor class =\" trix -content \" > </ trix -editor >
< div class =\" trix -content \" > Stored content here </ div >
默认的trix .css文件包括基本格式化内容的样式,包括子弹和编号列表,代码块和块引号 – 在class name trix -content下。我们鼓励您将这些样式用作起点,将它们复制到应用程序的CSS中,具有不同的类名称。
存储附件的文件
trix会自动接受已拖动或粘贴到编辑器中的文件,并将其插入文档中的附件。每个附件都被视为待处理,直到您将其远程存储并为trix提供永久性URL。
要存储附件,请收听trix -Attachment -Add事件。用XMLHTTPRequest上载附件的文件,并在完成后设置附件的URL属性。有关详细信息,请参见附件示例。
如果您不想接受删除或粘贴的文件,请在trix -file -peccept Event上致电Trix -File -File -peccept事件,该trix在trix -Attachment -Add事件之前派发。
通过编程编辑文本
您可以通过trix .Editor界面对trix编辑器进行编程操作,并在每个< trix -editor>元素上通过其编辑器属性提供。
trix-editor\”)
element.editor // is a trix .Editor instance\”>
var element = document . querySelector ( \" trix -editor\" ) element . editor // is a trix .Editor instance
了解文档模型
trix编辑器的格式化内容被称为文档,并表示为trix .Document类的实例。要获取编辑器的当前文档,请使用editor.getDocument方法。
element . editor . getDocument ( ) // is a trix .Document instance
您可以使用document.tostring方法将文档转换为未形式的JavaScript字符串。
var document = element . editor . getDocument ( ) document . toString ( ) // is a JavaScript string
不变性和平等
文档是不变的值。您在编辑器中进行的每个更改都用新文档代替了上一个文档。捕获编辑器内容的快照就像保留对其文档的参考一样简单,因为该文档永远不会随着时间的流逝而改变。 (这就是trix实现撤消的方式。)
要比较两个文档以保持平等,请使用document.isequalto方法。
var document = element . editor . getDocument ( ) document . isEqualTo ( element . editor . getDocument ( ) ) // true
获取和设置选择
trix文档构成为单独寻址字符的序列。文档中一个字符的索引称为位置,一个开始和端位置共同组成范围。
要获取编辑器的当前选择,请使用editor.getSelectedRange方法,该方法返回包含开始和终点位置的两元素数组。
element . editor . getSelectedRange ( ) // [0, 0]
您可以通过将范围阵列传递到editor.setselectedRange方法来设置编辑器的当前选择。
// Select the first character in the document element . editor . setSelectedRange ( [ 0 , 1 ] )
崩溃的选择
当范围的开始和端位置相等时,据说范围崩溃了。在编辑器中,一个崩溃的选择是闪烁的光标,而不是突出显示的文本。
为了方便起见,在使用折叠选择时,以下对SetSelectedRange的调用等效:
element . editor . setSelectedRange ( 1 ) element . editor . setSelectedRange ( [ 1 ] ) element . editor . setSelectedRange ( [ 1 , 1 ] )
方向运动
要通过文档进行编程方式移动光标或选择,请致电Editor.movecursorindirection或Editor.spandselectionDirection方法,具有方向参数。方向可以是“前进”或“向后”。
// Move the cursor backward one character element . editor . moveCursorInDirection ( \"backward\" ) // Expand the end of the selection forward by one character element . editor . expandSelectionInDirection ( \"forward\" )
将位置转换为像素偏移
有时,您需要在编辑器中给定位置的角色的X和Y坐标。例如,您可能需要绝对将弹出菜单元素放在编辑器的光标下方。
调用带有位置参数的getClientRectAtposition方法,以获取代表给定位置处角色的左侧和顶部偏移,宽度和高度的DOMRECT实例。
var rect = element . editor . getClientRectAtPosition ( 0 ) [ rect . left , rect . top ] // [17, 49]
插入和删除文本
编辑器接口提供了用于当前选择中插入,替换和删除文本的方法。
要插入或替换文本,请首先设置所选范围,然后调用下面的插入方法之一。 trix将首先删除任何选定的文本,然后将新文本插入所选范围的开始位置。
插入纯文本
要将未形式的文本插入文档中,请致电editor.insertstring方法。
// Insert “Hello” at the beginning of the document element . editor . setSelectedRange ( [ 0 , 0 ] ) element . editor . insertString ( \"Hello\" )
插入HTML
要将HTML插入文档中,请致电editor.inserthtml方法。 trix将首先将HTML转换为其内部文档模型。在此转换过程中,任何在trix文档中无法表示的格式都将丢失。
// Insert a bold “Hello” at the beginning of the document element . editor . setSelectedRange ( [ 0 , 0 ] ) element . editor . insertHTML ( \"<strong>Hello</strong>\" )
插入文件
要将DOM文件对象插入文档中,请调用editor.intertfile方法。 trix会插入文件的待处理附件,就像您已将其拖放并将其丢弃到编辑器上一样。
// Insert the selected file from the first file input element var file = document . querySelector ( \"input[type=file]\" ) . file element . editor . insertFile ( file )
插入内容附件
内容附件是HTML的独立单位,其行为就像编辑器中的文件一样。它们可以被移动或删除,但不能直接进行编辑,并且由文档模型中的单个字符位置表示。
要插入HTML作为附件,请创建带有内容属性的trix .Attachment,然后调用editor.insertattachment方法。内容附件中的HTML不受trix的文档转换规则的约束,并且将呈现为IS。
trix </span>\’ })
element.editor.insertAttachment(attachment)\”>
var attachment = new trix . Attachment ( { content : \'<span class=\"mention\">@ trix </span>\' } ) element . editor . insertAttachment ( attachment )
插入线路休息
要插入线路断开,请调用editor.insertline break方法,该方法在功能上等同于按返回键。
// Insert “Hello\\n” element . editor . insertString ( \"Hello\" ) element . editor . insertLineBreak ( )
删除文字
如果当前选择崩溃,则可以使用Editor.DeleteDirection方法在光标之前或之后模拟删除文本。
// “Backspace” the first character in the document element . editor . setSelectedRange ( [ 1 , 1 ] ) element . editor . deleteInDirection ( \"backward\" ) // Delete the second character in the document element . editor . setSelectedRange ( [ 1 , 1 ] ) element . editor . deleteInDirection ( \"forward\" )
要删除一系列文本,请首先设置选定的范围,然后以任何方向为参数调用Editor.Deleter.DeleteDirection。
// Delete the first five characters element . editor . setSelectedRange ( [ 0 , 4 ] ) element . editor . deleteInDirection ( \"forward\" )
使用属性和嵌套
trix表示格式为文档范围内应用的属性集。
默认情况下, trix支持内联属性粗体,斜体,HREF和罢工,以及块级属性heading1,Quote,quote,code,code,bullet和number。
应用格式
要将格式应用于当前选择,请使用editor.activateattribute方法。
element . editor . insertString ( \"Hello\" ) element . editor . setSelectedRange ( [ 0 , 5 ] ) element . editor . activateAttribute ( \"bold\" )
要设置HREF属性,请将URL作为第二个参数传递给Editor.activateatTribute。
trix\”)
element.editor.setSelectedRange([0, 4])
element.editor.activateAttribute(\”href\”, \”https://trix*-e**ditor.org/\”)\”>
element . editor . insertString ( \" trix \" ) element . editor . setSelectedRange ( [ 0 , 4 ] ) element . editor . activateAttribute ( \"href\" , \"https://trix*-e**ditor.org/\" )
删除格式
使用editor.deactivateattribute方法从选择中删除格式。
element . editor . setSelectedRange ( [ 2 , 4 ] ) element . editor . deactivateAttribute ( \"bold\" )
用崩溃的选择格式化
如果当选择折叠时激活或停用属性,则格式化更改将适用于任何后续呼叫对editor.insertstring插入的文本。
element . editor . activateAttribute ( \"italic\" ) element . editor . insertString ( \"This is italic\" )
调整嵌套水平
要调整引号,项目符号列表或编号列表的嵌套级别,请致电Editor.increasenestinglevel和editor.decreasenestinglevel方法。
element . editor . activateAttribute ( \"quote\" ) element . editor . increaseNestingLevel ( ) element . editor . decreaseNestingLevel ( )
使用撤消和重做
trix编辑器支持无限的撤消和重做。连续打字和格式变化以五秒的间隔合并在一起;所有其他输入更改均在撤消历史记录中单独记录。
致电editor.undo和editor.redo方法执行撤消或重做操作。
element . editor . undo ( ) element . editor . redo ( )
您通过编辑器接口进行的更改不会自动记录撤消条目。您可以通过使用描述参数调用editor.recordundoentry方法来保存自己的撤消条目。
element . editor . recordUndoEntry ( \"Insert Text\" ) element . editor . insertString ( \"Hello\" )
加载和保存编辑状态
用JSON.Stringify和Restore Saved State用editor.loadjson方法序列化编辑器的状态。序列化状态包括文档和当前选择,但不包括撤消历史记录。
