CKEditor5 和 Angular2 - 在编辑器内部单击获取插入符号的确切位置以获取数据
CKEditor5 & Angular2 - Getting exact position of caret on click inside editor to grab data
在 Angular2+ 中,当我在 CKEditor5 Balloon Editor
实例中单击时,我试图获取插入符号的确切位置。我将在页面上有几个实例,每个实例都通过 @ViewChildren
和 QueryList
动态表示(每个实例都是一个单独的编辑器)。
在高层次上,我试图在用户在气球编辑器中单击时触发一个方法,它将光标之前的所有文本存储在一个变量中,然后将光标之后的所有文本存储在另一个变量中。
即如果用户在 "world" 之后键入 Hello world this is a test
并在 div 内单击,它将在一个变量中存储 "Hello world",在另一个变量中存储 "this is a test"。
知道如何实现吗?我假设我需要创建 Position
的两个实例,然后以某种方式将其提供给 Range
,但我不知道如何提供 Position
正确的路径。
如果有人有仅适用于 CKEditor 5 的常规旧单个实例的工作方法,我将不胜感激。谢谢!
完整的解决方案如下所示:
const pos = editor.document.selection.getFirstPosition();
// If you want to get the text up to the root's boundary:
// const posStart = Position.createAt( pos.root );
// const posEnd = Position.createAt( pos.root, 'end' );
// If you want to get the text up to the current element's boundary:
const posStart = Position.createAt( pos.parent );
const posEnd = Position.createAt( pos.parent, 'end' );
const rangeBefore = new Range( posStart, pos );
const rangeAfter = new Range( pos, posEnd );
let textBefore = '';
let textAfter = '';
// Range is iterable and uses TreeWalker to return all items in the range.
// value is of type TreeWalkerValue.
for ( const value of rangeBefore ) {
if ( value.item.is( 'textProxy' ) ) {
textBefore += value.item.data;
}
}
for ( const value of rangeAfter ) {
if ( value.item.is( 'textProxy' ) ) {
textAfter += value.item.data;
}
}
console.log( textBefore );
console.log( textAfter );
您在此处使用 TreeWalker
获取某个范围内的所有项目并将您在此处找到的文本代理字符串化。
请注意,您会得到 TextProxy
s instead of normal Text
个节点,因为 tree walker 可能需要 return 文本节点的一部分(如果范围在该文本节点的中间结束)。
编辑: 要将内容字符串化为数据格式,(因此 - 包括 HTML 标记,而不仅仅是文本),您需要使用一些不同的方法:
function doStuff( editor ) {
const pos = editor.document.selection.getFirstPosition();
const posStart = Position.createAt( pos.root );
const posEnd = Position.createAt( pos.root, 'end' );
const rangeBefore = new Range( posStart, pos );
const rangeAfter = new Range( pos, posEnd );
const fragBefore = editor.data.getSelectedContent( new Selection( [ rangeBefore ] ) );
const fragAfter = editor.data.getSelectedContent( new Selection( [ rangeAfter ] ) );
console.log( editor.data.stringify( fragBefore ) );
console.log( editor.data.stringify( fragAfter ) );
}
在 Angular2+ 中,当我在 CKEditor5 Balloon Editor
实例中单击时,我试图获取插入符号的确切位置。我将在页面上有几个实例,每个实例都通过 @ViewChildren
和 QueryList
动态表示(每个实例都是一个单独的编辑器)。
在高层次上,我试图在用户在气球编辑器中单击时触发一个方法,它将光标之前的所有文本存储在一个变量中,然后将光标之后的所有文本存储在另一个变量中。
即如果用户在 "world" 之后键入 Hello world this is a test
并在 div 内单击,它将在一个变量中存储 "Hello world",在另一个变量中存储 "this is a test"。
知道如何实现吗?我假设我需要创建 Position
的两个实例,然后以某种方式将其提供给 Range
,但我不知道如何提供 Position
正确的路径。
如果有人有仅适用于 CKEditor 5 的常规旧单个实例的工作方法,我将不胜感激。谢谢!
完整的解决方案如下所示:
const pos = editor.document.selection.getFirstPosition();
// If you want to get the text up to the root's boundary:
// const posStart = Position.createAt( pos.root );
// const posEnd = Position.createAt( pos.root, 'end' );
// If you want to get the text up to the current element's boundary:
const posStart = Position.createAt( pos.parent );
const posEnd = Position.createAt( pos.parent, 'end' );
const rangeBefore = new Range( posStart, pos );
const rangeAfter = new Range( pos, posEnd );
let textBefore = '';
let textAfter = '';
// Range is iterable and uses TreeWalker to return all items in the range.
// value is of type TreeWalkerValue.
for ( const value of rangeBefore ) {
if ( value.item.is( 'textProxy' ) ) {
textBefore += value.item.data;
}
}
for ( const value of rangeAfter ) {
if ( value.item.is( 'textProxy' ) ) {
textAfter += value.item.data;
}
}
console.log( textBefore );
console.log( textAfter );
您在此处使用 TreeWalker
获取某个范围内的所有项目并将您在此处找到的文本代理字符串化。
请注意,您会得到 TextProxy
s instead of normal Text
个节点,因为 tree walker 可能需要 return 文本节点的一部分(如果范围在该文本节点的中间结束)。
编辑: 要将内容字符串化为数据格式,(因此 - 包括 HTML 标记,而不仅仅是文本),您需要使用一些不同的方法:
function doStuff( editor ) {
const pos = editor.document.selection.getFirstPosition();
const posStart = Position.createAt( pos.root );
const posEnd = Position.createAt( pos.root, 'end' );
const rangeBefore = new Range( posStart, pos );
const rangeAfter = new Range( pos, posEnd );
const fragBefore = editor.data.getSelectedContent( new Selection( [ rangeBefore ] ) );
const fragAfter = editor.data.getSelectedContent( new Selection( [ rangeAfter ] ) );
console.log( editor.data.stringify( fragBefore ) );
console.log( editor.data.stringify( fragAfter ) );
}