敲碎时间,铸造不朽的个人专栏
上一篇

CKEditor5——模型理解(六:Range)

广告
选中文字可对指定文章内容进行评论啦,→和←可快速切换按钮,绿色背景文字可以点击查看评论额。
大纲

上一节我们主要介绍了模型中的Position这个关键的类,今天我们开始学习Range这个类。简单来说的话,如果Position表示一个点的话,那么Range是不是可以理解为一条线段呢?这个线段有一个startPostion,endPosition以及线段的长度等属性,我们暂且这么认为,那么我们可以看看Range官方的文档

从文档中看到,Range类有五个属性:

Range属性

start:Position

end:Position

isCollapsed:boolean

isFlat:boolean

root:Element | DocumentFragment

除了我们理解的开始位置和结束位置外,还增加了是否折叠和是否平铺的布尔属性以及一个对模型跟文档的引用。

这里说明一下,当开始位置和结束位置相等的时候就是折叠的,否则为非折叠;而当开始位置和结束位置在同一个父节点中的时候就是平铺的,否则为非平铺的。这些属性的作用,我在后文中会用例子来介绍。

 

Range方法

大概看了一个range的方法,除了构造方法之外,其他的都是一些判断或者读取属性的方法,没有看到创建方法,其实Range的创建一般都是在writer中的,我们要创建Range,都是只用writer类来创建。

首先,Range有是三个contains方法,分别是

containsItem(item):boolean

containsPosition(position):boolean

containsRange(otherRange,[loose]):boolean

它们的作用是判断当前Range是否包含某个元素,是否包含某个位置,是否包含某个范围。

剩下的主要是一些读取属性的方法,比如:

getCommonAncestor():Element | DocumentFragment

读取Range两个端点共同的祖先元素
getContainedElement(): Element 

返回包含此Range的元素。

getDifference(otherRange):Array<Range>

计算出属于本Range而不属于otherRange的Range数组。

let range = model.createRange(
	model.createPositionFromPath( root, [ 2, 7 ] ),
	model.createPositionFromPath( root, [ 4, 0, 1 ] )
);
let otherRange = model.createRange( model.createPositionFromPath( root, [ 1 ] ), model.createPositionFromPath( root, [ 5 ] ) );
let transformed = range.getDifference( otherRange );

//这里是otherRange包含了range,因此返回的数组为空
// transformed array has no ranges because `otherRange` contains `range`

otherRange = model.createRange( model.createPositionFromPath( root, [ 1 ] ), model.createPositionFromPath( root, [ 3 ] ) );
transformed = range.getDifference( otherRange );
// 这里是otherRange与range的前面部分交叉,因此返回属于range且与otherRange交叉部分
// transformed array has one range: from [ 3 ] to [ 4, 0, 1 ]

otherRange = model.createRange( model.createPositionFromPath( root, [ 3 ] ), model.createPositionFromPath( root, [ 4 ] ) );
transformed = range.getDifference( otherRange );

//这个稍微复杂一点,交叉部分有两个,注意一定是属性range,但是要去除otherRange部分
// transformed array has two ranges: from [ 2, 7 ] to [ 3 ] and from [ 4 ] to [ 4, 0, 1 ]

getIntersection(otherRange): Array<Range>

返回此range与otherRange交叉部分。

let range = model.createRange(
	model.createPositionFromPath( root, [ 2, 7 ] ),
	model.createPositionFromPath( root, [ 4, 0, 1 ] )
);
let otherRange = model.createRange( model.createPositionFromPath( root, [ 1 ] ), model.createPositionFromPath( root, [ 2 ] ) );
//这里交叉部分为空,显然返回值没有
let transformed = range.getIntersection( otherRange ); // null - ranges have no common part

otherRange = model.createRange( model.createPositionFromPath( root, [ 3 ] ), model.createPositionFromPath( root, [ 5 ] ) );
//这里的交叉部分从otherRange的3开始到range的4,0,1结束
transformed = range.getIntersection( otherRange ); // range from [ 3 ] to [ 4, 0, 1 ]

getItems([options]) : Iterable.<Item>

返回此Range内所有Item元素的一个迭代器,通过迭代可以对元素进行一些操作。

getJoined(otherRange,[loose]):Range

返回此Range与otherRange连接而成的Range,如果没有共同部分,返回null

let range = model.createRange(
	model.createPositionFromPath( root, [ 2, 7 ] ),
	model.createPositionFromPath( root, [ 4, 0, 1 ] )
);
let otherRange = model.createRange(
	model.createPositionFromPath( root, [ 1 ] ),
	model.createPositionFromPath( root, [ 2 ] )
);
//没有共同的部分,返回null
let transformed = range.getJoined( otherRange ); // null - ranges have no common part

otherRange = model.createRange(
	model.createPositionFromPath( root, [ 3 ] ),
	model.createPositionFromPath( root, [ 5 ] )
);
transformed = range.getJoined( otherRange ); // range from [ 2, 7 ] to [ 5 ]

getMinimalFlatRanges():Array<Range>

计算并返回最小的展平范围集,它完全覆盖了这个范围。这个比较复杂,用到的时候可以查看官网

getPositions(): Iterable<Position>

返回一个迭代器,它迭代所有边界或包含在此范围内的位置。

getTransformedByOperation( operation ) → Array.<Range>

返回一个范围,该范围是通过给定操作转换此范围的结果。

getTransformedByOperations( operations ) → Array.<Range>

返回一个范围,该范围是通过多个操作转换此范围的结果。

getWalker()

创建一个以此范围为边界的 TreeWalker 实例。

// Create a range spanning over the entire root content:
const range = editor.model.createRangeIn( editor.model.document.getRoot() );

// Iterate over all items in this range:
//这个例子起到迭代指定Range内元素,并对元素进行操作的作用
for ( const value of range.getWalker() ) {
	console.log( value.item );
}

剩下的几个is判断方法暂时不做介绍了,用到的时候再查看也可以。

版权声明:著作权归作者所有。

X

欢迎加群学习交流

联系我们