【问题标题】:Flex: Listening for 'Hover' over Link in text areaFlex:在文本区域中的链接上侦听“悬停”
【发布时间】:2009-08-03 14:29:49
【问题描述】:

我试图找出链接何时在显示 html 文本的文本区域中“悬停”。 我想知道是否可以监听光标更改类型的事件。我在文档中找不到任何内容。 有谁知道我可以在这里收听什么活动?

谢谢

【问题讨论】:

  • 当你试图让“Flex”有点“HTML”的时候,这会很痛苦......

标签: apache-flex actionscript-3


【解决方案1】:

这是一个非常有趣的问题。使用 Cay 的建议,我想到了一种方法,该方法将返回 Rectangle 对象的 Array,对应于文本的位置。我使用复数是因为可能需要多个矩形,如果文本被敲击的话。

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% 的 alpha 绘制,因此它们是不可见的。

// 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】:

您无法分配侦听器,但作为一种解决方法,您可以检查鼠标的位置并确定它何时悬停在文本的某些部分...一旦确定链接的矩形(请参阅 TextField.getCharBoundaries() ) 你可以创建一个小精灵来监听事件,或者检查矩形是否包含 enterFrame 上的 Point(mouseX, mouseY)。

【讨论】:

    【解决方案3】:

    AFAIK 这是不可能的。您可以使用 CSS 为翻转时的链接设置样式(这本身就是另一个痛苦),但您不能将翻转捕获为 AS 事件。您可以使用LINK 事件捕获对链接的点击。

    【讨论】:

    • 谢谢。那正是我所想。嗯……不知道有没有办法在光标发生变化时进行监听。
    • 我认为当鼠标改变时你听不到(而且我几乎可以肯定它不是)这是一个内置的列表 mouse events 它不包括你的正在寻找。
    【解决方案4】:

    您可以使用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
    }
    

    【讨论】:

      猜你喜欢
      • 2023-03-14
      • 2013-01-30
      • 2015-08-05
      • 1970-01-01
      • 2019-01-29
      • 2013-04-14
      • 2018-04-17
      • 1970-01-01
      • 2012-10-24
      相关资源
      最近更新 更多