2009-08-03 34 views
5

Tôi đang cố gắng tìm hiểu thời điểm liên kết được 'di chuột qua' trong vùng văn bản hiển thị văn bản html. Tôi tự hỏi nếu nghe một loại thay đổi con trỏ của sự kiện có thể là cách. Tôi không thể tìm thấy bất cứ điều gì trong các tài liệu. Có ai có ý tưởng gì về sự kiện tôi có thể nghe ở đây không?Flex: Lắng nghe 'Di chuột' qua Liên kết trong vùng văn bản

Cảm ơn

+0

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 ... –

Trả lời

3

Đó 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.

+0

Cảm ơn - đánh giá cao sự trợ giúp. – Chin

+0

Bạn được chào đón. :) – evilpenguin

+0

lớp phủ dường như không bao gồm mọi chữ cái, nhưng dù sao đi nữa là một giải pháp tuyệt vời! – Hwang

1

AFAIK điều này là không thể. Bạn có thể sử dụng CSS để tạo kiểu liên kết trên rollover (đây là một cơn đau khác cho chính nó) nhưng bạn không thể nắm bắt được rollover như một sự kiện AS. Bạn có thể nắm bắt nhấp chuột của liên kết bằng sự kiện LINK.

+0

nhờ. đó là những gì tôi nghĩ. Hmmm ... Tôi tự hỏi nếu có một cách để lắng nghe khi con trỏ thay đổi. – Chin

+0

Tôi không nghĩ rằng bạn có thể nghe khi chuột thay đổi (và tôi gần như chắc chắn nó là không) Dưới đây là danh sách các sự kiện [chuột được tạo] [http://livedocs.adobe.com/flash/ 9.0/ActionScriptLangRefV3/flash/events/MouseEvent.html) và nó không bao gồm những gì bạn đang tìm kiếm. –

2

Bạn không thể chỉ định người nghe, nhưng như một giải pháp thay thế, bạn có thể kiểm tra vị trí của con chuột và xác định thời điểm nó di chuyển một phần văn bản ... Khi bạn xác định hình chữ nhật của liên kết (xem TextField.getCharBoundaries ()) bạn có thể tạo một sprite nhỏ để nghe các sự kiện, hoặc kiểm tra xem hình chữ nhật có chứa Point (mouseX, mouseY) trên enterFrame hay không.

1

Bạn có thể sử dụng sự kiện TextEvent.LINK. Thực hiện theo các thực hiện để appclications di động:

while(html.search("http://") != -1){ 
    html = html.replace("http://.", "event:"); 
    //it's necessary that the link contains the tag "event:" to the TextEvent.LINK event works. 
} 
StyleableTextField(textArea.textDisplay).htmlText = html; 
StyleableTextField(textArea.textDisplay).addEventListener(TextEvent.LINK, link_clickHandler); 
private function link_clickHandler(event:TextEvent):void 
{ 
    var url:String = "http://" + event.text; 
    // event.text contains the clicked URL 
} 
Các vấn đề liên quan