04.19
Описание проблемы:
Если вы хотите чтобы ссылки, включенные в текстовые блоки, были активными, свойство selectable должно принимать значение true. Иногда это сбивает с толку пользователей.
Решение:
Создание собственного компонента LinkTextArea, расширяющего TextArea, который будет рассылать соответствующе событие link.
Объяснение:
Выходом их этой ситуации является создание компонента LinkTextArea, расширяющего TextArea. Переопределяя функцию set selectable, мы можем добавть обработчик событий, чтоб отлавливать все клики в TextArea. Наш onClick обработчик будет брать свойство url (если оно есть) и рассылать событие link.
Т.к. мы переопределяем функцию set selectable, то можем вызывать наш обработчик в случае, когда свойство selectable равно true, и переставать вызывать его, когда selectable равно false. Таким образом мы не повлияем на функциональность TextArea когда свойство selectable = true.
Наш onClick обработчик:
1. Определяет символ в месте где щёлкнули мышкой;
2. Определяет TextRange состоящей из этого символа;
3. Берет свойство url нашего TextRange (если оно определенно);
4. Если определенно, парсим урл и добавляем его к событию flash.events.TextEvent.LINK, которое мы рассылаем при помощи вызова dispatchEvent.
ПРИМЕЧАНИЕ: когда url является событием, Флэш автоматически отрезает "event:" часть ссылки перед рассылкой события. Чтобы сохранить совместимость, нам надо вручную удалять ее перед рассылкой сообщения.
Код:
{
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.TextEvent;
import mx.core.mx_internal;
import mx.core.UITextField;
import mx.controls.TextArea;
import mx.controls.textClasses.TextRange;
import mx.events.FlexEvent;
use namespace mx_internal;
public class LinkTextArea extends TextArea
{
public function LinkTextArea()
{
super();
addEventListener(FlexEvent.CREATION_COMPLETE, onCreationComplete);
}
protected function onCreationComplete(pEvent:FlexEvent):void
{
selectable = false;
}
// Переопределяем свойство selectable так, чтоб мы могли добавлять наш
// обработчик onClick когда selectable установленно в true, либо удалять
// обработчик, если selectable равно false - позволяя таким образом
// нормально работать стандартным обработчикам.
override public function set selectable(pSelectable:Boolean):void
{
super.selectable = pSelectable;
if (textField)
{
textField.selectable = pSelectable;
}
else
{
// Если мы пытаемся установить значение свойству selectable до того как
// компонент проинициализируется, то нам надо отложить передачу команды
// текстовому полю (которое пока ещё не создалось) до тех пор, пока
// не будет завершенна инициализация.
callLater(function(pSelectable:Boolean):void
{
textField.selectable = pSelectable;
}, [pSelectable]);
}
if (!pSelectable)
{
addEventListener(MouseEvent.CLICK, onClick);
}
else
{
UITextField(textField).setSelection(-1, -1);
removeEventListener(MouseEvent.CLICK, onClick);
}
}
protected function onClick(pEvent:MouseEvent):void
{
// Находим букву по коорой кликнули мышкой
var index:int = textField.getCharIndexAtPoint(pEvent.localX, pEvent.localY);
if (index != -1)
{
// преобразуем букву к TextRange, чтобы иметь возможность
// извлечь свойство url
var range:TextRange = new TextRange(this, false, index, index + 1);
// убеждаемся что TextRange содержит url
if (range.url.length > 0)
{
// Стандартный clickEvent отрезает "event:" подстроку свойства url.
// Для сохранения совместимости тоже отрежем "event:"
var url:String = range.url;
if (url.substr(0, 6) == 'event:')
{
url = url.substring(6);
}
// Рассылаем событие "link" с адресом ссылки в теле события
dispatchEvent(new TextEvent(TextEvent.LINK, false, false, url));
}
}
}
}
}
Оригинал: Make Text Area Links Active Without Making Text Selectable
Перевод: WD479


557 comments so far
Add Your Comment