Đó là một vấn đề rất thú vị. Sử dụng gợi ý của Cay, tôi đã nghĩ ra một phương thức trả về một đối tượng Array
của Rectangle
, coresponding đến vị trí của văn bản. Tôi đang sử dụng số nhiều vì có thể có nhiều hình chữ nhật cần thiết, nếu văn bản là từ bị cắt.
function getPhraseLocation(phrase:String, field:TextField):Array {
// initialise the return array
var locations:Array = new Array();
// find the first and last chars
var firstChar = field.text.indexOf(phrase);
var lastChar = firstChar+phrase.length;
// determine the bounding rectangle of the first char
var firstCharRect = field.getCharBoundaries(firstChar);
var crtLocation:Rectangle = new Rectangle(firstCharRect.left,firstCharRect.top,firstCharRect.width,firstCharRect.height);
// while there are chars left in the string
var crtChar:uint = firstChar;
while (++crtChar<lastChar)
// if they're on the same line, expand the current rectangle
if (field.getCharBoundaries(crtChar).y==crtLocation.y) crtLocation.width = uint(crtLocation.width)+field.getCharBoundaries(crtChar).width;
// if they're on the next line, due to word wrapping, create a new rectangle
else {
locations.push(crtLocation);
var crtCharRect = field.getCharBoundaries(crtChar);
crtLocation = new Rectangle(crtCharRect.left,crtCharRect.top,crtCharRect.width,crtCharRect.height);
}
// add the last rectangle to the array
locations.push(crtLocation);
// return the array
return(locations);
}
Giả sử chúng tôi tạo ra TextField
như vậy:
var field:TextField = new TextField();
this.addChild(field);
// move the text field to some random coordinates
field.x = 50;
field.y = 50;
// set wordwrap to true, to test the multiline behaviour of our function
field.wordWrap = true;
// set a smaller width than our text
field.width = 300;
// disable selectability, I'm not sure it would work properly, anyway
field.selectable = false;
// fill the textfield with some random html text
field.htmlText = 'Lorem ipsum dolor sit amet, consectetur adipiscing <a href="http://www.stackoverflow.com">elit. Aliquam et</a> elementum lorem. Praesent vitae nunc at mi venenatis auctor.';
Bây giờ, để có một người biết lắng nghe sự kiện, chúng ta phải tạo một đối tượng và vẽ các hình chữ nhật trên văn bản thực tế. Các hình chữ nhật được vẽ ở 0% alpha, vì vậy chúng không nhìn thấy được.
// create a sprite and add it to the display list
var overlay:Sprite = new Sprite();
this.addChild(overlay);
// enable mouse actions on it and make the cursor change on hover
overlay.mouseEnabled = true;
overlay.buttonMode = true;
// call the function that returns the size and position of the bounding boxes
var locationArray:Array = getPhraseLocation('elit. Aliquam et',field);
// draw each rectangle in white transparent fill
for each (var bounds:Rectangle in locationArray) {
overlay.graphics.beginFill(0xff0000,0);
overlay.graphics.drawRect(bounds.x+field.x-overlay.x, bounds.y+field.y-overlay.y, bounds.width, bounds.height);
overlay.graphics.endFill();
}
Sau đó, thêm event listener cho MouseOver
:
overlay.addEventListener(MouseEvent.MOUSE_OVER, mouseOverHandler);
function mouseOverHandler(evt:MouseEvent):void {
trace('mouse over key phrase');
// do whatever else you want to do
}
Thật không may, bởi vì chúng tôi vẽ một cái gì đó trên văn bản thực tế, các liên kết trở thành không hoạt động. Như vậy, chúng ta phải thêm người nghe sự kiện cho nhấp chuột, cũng:
overlay.addEventListener(MouseEvent.CLICK, clickHandler);
function clickHandler(evt:MouseEvent):void {
navigateToURL(new URLRequest('http://www.stackoverflow.com'));
}
Bởi vì trước đây chúng tôi thiết lập các thuộc tính buttonMode
để true
, chuột sẽ thay đổi con trỏ của nó, cư xử chính xác như nó đã có nếu liên kết trong văn bản sẽ đã làm việc.
Tôi đã xác định rất nhiều biến, để giữ cho mã dễ hiểu hơn. Mã có thể được rút ngắn và tối ưu hóa, nhưng nó cũng hoạt động tốt như nó.
Đó là một giải pháp khắc phục cho các tác vụ đơn giản nhất, nhưng nó hoạt động. Hy vọng nó có ích.
này đã sẵn sàng một nỗi đau khi bạn cố gắng để làm cho "Flex" một chút "HTML" cách ... –