首页 > 代码库 > Flash TextField selectable bug block TextEvent.Link solution

Flash TextField selectable bug block TextEvent.Link solution

There is an old version Felx SDK bug(in my case it‘s Flex SDK v3.3.0.4852) that when TextField.selectable is set to false, link event on the textfield will be blocked. So if you have added html text including a link into the textfield, e.g.:

var textField:TextField = new TextField();  
textField.htmlText = "This is a testing message. <a href=http://www.mamicode.com/‘event:clickHandler‘>Click to see more.";  
textField.selectable = false;  

Then when you click "Click", it will not trigger "clickHandler" function. This will also happen when the anchor‘s href value is a URL, e.g.:

var textField:TextField = new TextField();  
textField.htmlText = "This is a testing message. <a href=http://www.mamicode.com/‘http://www.google.com‘ target=‘_blank‘>Click to see more.";  
textField.selectable = false;  

When click "Click", browser will not open the Google page in a new tab. But you can actually right click on the link and select "Open" to open it.

The previous two situations are both caused by selectable property set to false using Flex SDK 3.3.0.4852. I have three solutions to fix this:

1. Set selectable to true;
2. Change Flex SDK to newly version;
3. Register event listener to handle click event;

The first two solutions are simple, I‘ll give some more details on the third solution which will not change selectable attribute nor SDK. The main idea is register MouseClick event on the textfield, when user click the text, check whether the position is on the link. If the mouse click is on the link text, use "navigateToURL" function to open the link.

1. New a TextField object and set accordingly:

var textField:TextField = new TextField();  
textField.htmlText = "Testing message. <a href=http://www.mamicode.com/‘http://www.google.com‘ target=‘_blank‘>Click to see more.";  
textField.selectable = false;  
var textFmtLink:TextFormat = new TextFormat();  
formatter.color = "0x3366BB";  
formatter.underline = true;  

2. Use "formatFieldLinkText" function to formate the link text and register event listener to handle click event:

    formatFieldLinkText(textField, textFmtLink);  
  
   protected function formatFieldLinkText(textField:TextField, linkFormat:TextFormat):void  
 {  
    var fieldText:String = textField.text;  
    var textFormat:TextFormat = textField.getTextFormat();  
    var formatedText:String = "";  
    var linkObjArray:Array = [];  
     
    var textArray:Array = fieldText.split(/(<a\s[^>]+>.+?<\/a>)/gi );  
    var linkTextPattern:RegExp = new RegExp("(?i)[^>]*(?=</a>)" );  
    var linkUrlPattern:RegExp = /href\s*=\s*[‘"]([^‘"]+)[‘"]/i;  
    var linkTargetPattern:RegExp = /target\s*=\s*[‘"]([^‘"]+)[‘"]/i ;  
    for (var i:int = 0; i < textArray.length; i++)  
    {  
        //plain text  
        if (textArray[i].toString().search(/(<a\s[^>]+>.+?<\/a>)/gi )==-1)  
        {  
            formatedText+=textArray[i].toString();  
            continue;  
        }  
         
        var linkText:String = linkTextPattern.exec(textArray[i]);  
        // check if linkText is blank  
        if (isBlank(linkText))  
        {  
            return;  
        }  
        var linkUrl:Array = linkUrlPattern.exec(textArray[i]);  
        var linkTarget:Array = linkTargetPattern.exec(textArray[i]);  
        if (linkUrl==null)  
        {  
            return;  
        }  
        var linkObj:Object = new Object();  
        linkObj.href = linkUrl== null?"" :linkUrl[1];  
        linkObj.target = linkTarget== null?"" :linkTarget[1];  
        linkObj.linkBegin = formatedText.length;  
        linkObj.linkEnd = formatedText.length + linkText.length;  
        linkObjArray.push(linkObj);  
         
        formatedText+=linkText;  
         
        textField.addEventListener(MouseEvent.CLICK, hyperLinkClicked);  
    }  
    textField.text = formatedText;  
    textField.setTextFormat(textFormat);  
    for (var j:int = 0; j < linkObjArray.length; j++)  
    {  
        textField.setTextFormat(linkFormat, linkObjArray[j].linkBegin, linkObjArray[j].linkEnd);  
    }  
     
    var href:String = "";  
    var target:String = "";  
    function hyperLinkClicked (e:MouseEvent):void  
    {  
        var idx:int = e.currentTarget.getCharIndexAtPoint(e.localX, e.localY);  
        if (posOnLink(idx))  
        {  
            var request:URLRequest = new URLRequest(href);  
            navigateToURL(request, target);  
        }  
    }  
     
    // can optimize the search method  
    function posOnLink(idx:int):Boolean  
    {  
        for (var k:int = 0; k < linkObjArray.length; k++)  
        {  
            if (idx >= linkObjArray[k].linkBegin && idx < linkObjArray[k].linkEnd)  
            {  
                href = linkObjArray[k].href;  
                target = linkObjArray[k].target;  
                return true ;  
            }  
        }  
        return false ;  
    }  
}  

(本文系从原博客迁移至此,并进行部分编辑。原文链接:http://thewaychung.iteye.com/blog/1974209)

Flash TextField selectable bug block TextEvent.Link solution