Flex: прослушивание «Hover» над ссылкой в ​​текстовой области - PullRequest
5 голосов
/ 03 августа 2009

Я пытаюсь выяснить, когда ссылка «зависла» в текстовой области, отображающей HTML-текст. Интересно, может ли быть подход к прослушиванию события типа изменения курсора. Я не могу найти ничего в документах. Кто-нибудь знает, какое событие я мог бы послушать здесь?

Спасибо

Ответы [ 4 ]

3 голосов
/ 04 августа 2009

Это очень интересная проблема. Используя предложение Кея, я подумал о методе, который бы возвращал Array из Rectangle объектов, ядро ​​которых соответствовало бы местам текста. Я использую множественное число, потому что может быть несколько прямоугольников, если текст переносится по слову.

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);
}

Давайте предположим, что мы создали TextField примерно так:

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.';

Теперь, чтобы получить прослушиватель событий, мы должны создать объект и нарисовать прямоугольники поверх реального текста. Прямоугольники нарисованы в 0% альфа, поэтому они невидимы.

// 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();
}

Затем добавьте прослушиватель событий для MouseOver:

overlay.addEventListener(MouseEvent.MOUSE_OVER, mouseOverHandler);
function mouseOverHandler(evt:MouseEvent):void {
    trace('mouse over key phrase');
    // do whatever else you want to do
}

К сожалению, поскольку мы рисуем что-то поверх реального текста, ссылки становятся неактивными. Таким образом, мы должны добавить прослушиватели событий для клика, а также:

overlay.addEventListener(MouseEvent.CLICK, clickHandler);
function clickHandler(evt:MouseEvent):void {
    navigateToURL(new URLRequest('http://www.stackoverflow.com'));
}

Поскольку мы ранее установили атрибут buttonMode на true, мышь изменит свой курсор, ведя себя точно так же, как если бы ссылка в тексте работала.

Я определил множество переменных, чтобы код был проще для понимания. Код может быть сокращен и оптимизирован, но он также должен нормально работать.

Это адский обходной путь для самых простых задач, но он работает. Надеюсь, это полезно.

2 голосов
/ 04 августа 2009

Вы не можете назначить слушателей, но в качестве обходного пути вы можете проверить положение мыши и определить, когда она наводит курсор на некоторую часть текста ... После определения прямоугольника ссылки (см. TextField.getCharBoundaries () ) вы можете либо создать небольшой спрайт для прослушивания событий, либо проверить, содержит ли прямоугольник Point (mouseX, mouseY) на enterFrame.

1 голос
/ 28 февраля 2012

Вы можете использовать событие TextEvent.LINK. Следуйте за реализацией для мобильных приложений:

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
}
1 голос
/ 03 августа 2009

AFAIK это невозможно. Вы можете использовать CSS для стилизации ссылки при опрокидывании (что является еще одной проблемой), но вы не можете захватить опрокидывание как событие AS. Вы можете зафиксировать щелчок ссылки, используя событие LINK .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...