使用Raphaël 库,您可以创建集合,它们是包含 Raphaël 元素的类数组对象,并且可以在调用元素方法时隐式循环这些元素。问题在于,尽管集合类似于数组,但并非原型中的所有函数Array
都可用于 Raphaël 集合,包括Array.concat()
. 如何将两个 Raphaël 集合连接成一个新集合?我不想修改任何一个原始集。
1 回答
好吧,我想出了一个办法。秘诀在于 Raphaël 集有一个未记录的属性,称为items
,它是该集所包含的 Raphaël 元素的普通数组。
Raphaël 集确实有一些类似于Array.splice()
方法的东西,它用于从数组中删除和插入元素。的语法Array.splice()
是anArray.splice(startingIndex, numberOfItemsToRemove, itemToInsert[, anotherItemToInsert...])
. 该函数创建一个空集合,它们只是splice
将两个现有集合中的项目放入新集合中。在这种情况下,两者startingIndex
和numberOfItemsToRemove
都应该是0
因为一个新集合有一个length
of 0
,这意味着唯一的索引是0
并且你不可能删除多个0
元素。
下面的函数利用了 JavaScript 的function.apply()
on 方法splice()
(如splice.apply()
)。apply()
接受两个参数:分配给this
函数内部关键字的值和成为函数参数的数组。我们可以创建一个数组apply()
作为参数传递给splice()
. 该数组中的前两项是startingIndex
和numberOfItemsToRemove
,因此它们都将设置为0
。所有后续参数都是要插入到新集合中的项目。我们可以用 初始化这个数组[0, 0]
,它是一个真正的数组,它确实有concat()
方法。我们现在要做的就是concat()
每个集合的元素,我们可以从item
集合的属性中获取到[0, 0]
,创建一个参数数组,这些参数将传递给splice()
新的空集的方法。
function concatSets(paper, setA, setB){
var newSet = paper.set(); // Creates a new, empty set
newSet.splice.apply(newSet, [0, 0].concat(setA.items, setB.items));
return newSet;
}
下面的函数可以根据需要连接任意数量的集合;只需传入一个集合数组作为第二个参数,并将纸对象作为第一个参数。如果arrayOfSets.length == 1
,则该函数只是创建该集合的副本。
function concatManySets(paper, arrayOfSets){
var i, newSet, argsToPass;
argsToPass = [0, 0]; // The first two parameters of a normal call to Array.splice()
newSet = paper.set(); // Creates a new, empty set
for(i = 0; i < arrayOfSets.length; i++){
argsToPass = argsToPass.concat(arrayOfSets[i].items);
}
newSet.splice.apply(newSet, argsToPass);
return newSet;
}