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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
@Override public void actionPerformed(ActionEvent e) {//触发此动作时执行 for (int i = 0; i < 10; i++) { if (e.getSource() == numberButtons[i]) {//返回最初发生 Event 的对象,那个对象被触发,就返回这个对象 textField.setText(textField.getText().concat(String.valueOf(i))); } } if (e.getSource() == decButton) { textField.setText(textField.getText().concat(".")); } if (e.getSource() == addButton) { num1 = Double.parseDouble(textField.getText()); operator = '+'; textField.setText(""); } if (e.getSource() == subButton) { num1 = Double.parseDouble(textField.getText()); operator = '-'; textField.setText(""); } if (e.getSource() == mulButton) { num1 = Double.parseDouble(textField.getText()); operator = '*'; textField.setText(""); } if (e.getSource() == divButton) { num1 = Double.parseDouble(textField.getText()); operator = '/'; textField.setText(""); } if (e.getSource() == equButton) { num2 = Double.parseDouble(textField.getText()); switch (operator) { case '+': result = num1 + num2; break; case '-': result = num1 - num2; break; case '*': result = num1 * num2; break; case '/': result = num1 / num2; break; } textField.setText(String.valueOf(result)); num1 = result; } if (e.getSource() == clrButton) { textField.setText(""); } if (e.getSource() == delButton) { String string = textField.getText(); textField.setText(""); for (int i = 0; i < string.length() - 1; i++) { textField.setText(textField.getText() + string.charAt(i)); } } } }请注释出每一步在做什么
06-02

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值