Flex中,如何获取TextArea中的光标的位置
2013-05-06 18:38
806 查看
要获取光标的index很容易,其实Flash原本的flash.text.TextField就提供这个功能,但在Flex里却没有把它暴露出来。不理解Adobe是怎么想的。
要使用原本Flash里就支持的这个功能很简单。mx.controls.TextArea里负责渲染的实际上是一个mx.core.UITextField,继承自mx.core.FlexTextField;后者又继承自flash.text.TextField。只要得到TextArea里的TextField就能使用它原本就支持的功能。
可是Flex的TextArea里textField是protected的,从外部无法获取,除非继承TextArea;TextArea.getTextField()方法是在mx_internal命名空间里的,不使用这个命名空间也无法调用。
于是我采用的办法是导入并使用mx.core.mx_internal命名空间,然后调用getTextField()方法来得到TextField。
导入和使用命名空间的代码:
import mx.core.mx_internal;
use namespace mx_internal;
那么获取当前光标index的方法就是:
public function getCaretIndex(ta : TextArea) : int {
return (ta.getTextField() as TextField).caretIndex;
}
如果是htmlText,index可能与预期的不同。参考这里的解决办法:http://www.flexer.info/2008/03/26/find-cursor-position-in-a-htmltext-object-richtexteditor-textarea-textfield-update/
获取光标的坐标则很麻烦。首先Flash的TextField本身似乎不直接支持这个操作,只支持它的逆操作:从坐标点获取字符。
还好TextField支持通过index来得到字符的边界(bounds),于是我们可以把光标右边的字符(也就是text.charAt(caretIndex))的左上角坐标当作是光标的坐标。
问题是光标位置所对应的index很可能是字符串的末尾,那么它的右边的字符是空串('');又或者光标右边的字符是换行符(Flex的TextArea里按回车似乎只会得到\r……)。这两种情况都会导致TextField.getCharBoundaries()的调用返回null,让事情变得很麻烦。
所以只能用很hacky的办法来算出光标的坐标了。TextField在渲染文字的时候,会在左边和上面各留出2像素的空位,所以下面的代码里可以看到有个magic number是2。这个数字是在TextLineMetrics类的文档里看到的。
public
function getCaretLocation(ta : TextArea) : Point {
var tf : TextField = ta.getTextField() as TextField;
var index : Number = tf.caretIndex;
var x : Number, y : Number;
var rect : Rectangle;
if ('' == ta.text.charAt(index)) {
if (0 == index) {
// the TextArea is empty
x = 2;
y = 2;
} else if ('\n' == ta.text.charAt(index - 1) || '\r' == ta.text.charAt(index - 1)) {
// at the start of a new line, and also at the end of a the line
// use lineHeight * lineIndex + yPadding as y
x = 2;
y = tf.getLineMetrics(0).height * (tf.getLineIndexOfChar(index - 1) + 1) + 2;
} else {
// at the end of a line
// use the bounds of the charater to the left of caret, and add the width of it to x
rect = tf.getCharBoundaries(index - 1);
x = rect.x + rect.width;
y = rect.y;
}
} else {
if ('\n' == ta.text.charAt(index) || '\r' == ta.text.charAt(index)) {
// at the start of a line, but not at the end of the line
x = 2;
y = tf.getLineMetrics(0).height * tf.getLineIndexOfChar(index) + 2;
} else {
// in middle of a line
rect = tf.getCharBoundaries(index);
x = rect.x;
y = rect.y;
}
}
return new Point(x, y);
}
希望上面的代码有用吧。写这玩儿快让我对Adobe绝望了……
要使用原本Flash里就支持的这个功能很简单。mx.controls.TextArea里负责渲染的实际上是一个mx.core.UITextField,继承自mx.core.FlexTextField;后者又继承自flash.text.TextField。只要得到TextArea里的TextField就能使用它原本就支持的功能。
可是Flex的TextArea里textField是protected的,从外部无法获取,除非继承TextArea;TextArea.getTextField()方法是在mx_internal命名空间里的,不使用这个命名空间也无法调用。
于是我采用的办法是导入并使用mx.core.mx_internal命名空间,然后调用getTextField()方法来得到TextField。
导入和使用命名空间的代码:
import mx.core.mx_internal;
use namespace mx_internal;
那么获取当前光标index的方法就是:
public function getCaretIndex(ta : TextArea) : int {
return (ta.getTextField() as TextField).caretIndex;
}
如果是htmlText,index可能与预期的不同。参考这里的解决办法:http://www.flexer.info/2008/03/26/find-cursor-position-in-a-htmltext-object-richtexteditor-textarea-textfield-update/
获取光标的坐标则很麻烦。首先Flash的TextField本身似乎不直接支持这个操作,只支持它的逆操作:从坐标点获取字符。
还好TextField支持通过index来得到字符的边界(bounds),于是我们可以把光标右边的字符(也就是text.charAt(caretIndex))的左上角坐标当作是光标的坐标。
问题是光标位置所对应的index很可能是字符串的末尾,那么它的右边的字符是空串('');又或者光标右边的字符是换行符(Flex的TextArea里按回车似乎只会得到\r……)。这两种情况都会导致TextField.getCharBoundaries()的调用返回null,让事情变得很麻烦。
所以只能用很hacky的办法来算出光标的坐标了。TextField在渲染文字的时候,会在左边和上面各留出2像素的空位,所以下面的代码里可以看到有个magic number是2。这个数字是在TextLineMetrics类的文档里看到的。
public
function getCaretLocation(ta : TextArea) : Point {
var tf : TextField = ta.getTextField() as TextField;
var index : Number = tf.caretIndex;
var x : Number, y : Number;
var rect : Rectangle;
if ('' == ta.text.charAt(index)) {
if (0 == index) {
// the TextArea is empty
x = 2;
y = 2;
} else if ('\n' == ta.text.charAt(index - 1) || '\r' == ta.text.charAt(index - 1)) {
// at the start of a new line, and also at the end of a the line
// use lineHeight * lineIndex + yPadding as y
x = 2;
y = tf.getLineMetrics(0).height * (tf.getLineIndexOfChar(index - 1) + 1) + 2;
} else {
// at the end of a line
// use the bounds of the charater to the left of caret, and add the width of it to x
rect = tf.getCharBoundaries(index - 1);
x = rect.x + rect.width;
y = rect.y;
}
} else {
if ('\n' == ta.text.charAt(index) || '\r' == ta.text.charAt(index)) {
// at the start of a line, but not at the end of the line
x = 2;
y = tf.getLineMetrics(0).height * tf.getLineIndexOfChar(index) + 2;
} else {
// in middle of a line
rect = tf.getCharBoundaries(index);
x = rect.x;
y = rect.y;
}
}
return new Point(x, y);
}
希望上面的代码有用吧。写这玩儿快让我对Adobe绝望了……
相关文章推荐
- C#-WinForm-如何获取文本框(TextBox)中鼠标,光标位置
- 获取Textarea 元素当前的光标位置及document.selection.createRange()资料
- Flex4如何设置光标位置,让它靠后呢?适用TextInput、TextArea
- 获取div编辑框,textarea,input text的光标位置 兼容IE,FF和Chrome的方法介绍
- 如何用Javascript获得TextArea中的光标位置
- javascript获取textarea光标位置,内容方法(IE, Firefox)
- javascript获取textarea光标位置,内容方法(IE, Firefox)
- 获取textarea的光标位置
- 如何在textarea的光标位置插入文字
- 获取 Textarea 的光标位置
- javascript获取textarea中光标的位置 兼容
- JavaScript 获取/设置光标位置,兼容Input&&TextArea
- JavaScript 获取/设置光标位置,兼容Input&&TextArea
- JS获取文本框(input和textarea)中光标位置
- js 如何获取文本框中光标索引位置
- js获取textarea或者input光标位置,控制光标位置
- 获取textarea的光标位置,并插入数据
- Flex 如何获取Textarea的选择文本
- javascript获取textarea光标选择位置和内容方法(IE, Firefox)
- 获取 Textarea 元素当前的光标位置及document.selection.createRange()资料