`
thewaychung
  • 浏览: 22425 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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='event:clickHandler'>Click</a> 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.google.com' target='_blank'>Click</a> 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.google.com' target='_blank'>Click</a> 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 ;
            }
        }
 

 

1
2
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics