你怎么prevent箭头向上/向下默认行为的文本字段?你怎么、箭头、字段、文本

2023-09-08 13:33:30 作者:愛哭的毛毛蟲

我想提出一个输入框的关键字,而用户写我的插入位置下方的列表上显示建议的关键字。 输入字段是单行线,所以我现在用的箭头上/下键选择建议,并输入插入它。 而它的主要工作,与大不同的是,上/下键也改变插入符位置的开头/结尾的文本字段

I am making a input field for keywords, and while the users writing I'm displaying suggestions for keyword on a list underneath the caret position. The input field is single line, so I am using the arrow up/down key to select a suggestion and Enter to insert it. And it's mostly working, with the big exception that the up/down key also changes the caret position to the begining/ending of the TextField.

我已经试过用 preventDefault() stopImmediatePropagation() KeyboardEvent.KEY_DOWN 事件监听器,我也用它来改变选择的建议,但是这不会改变任何东西。 我查了CARRET还没有移动时 KeyboardEvent.KEY_DOWN 事件被激发,卜视觉上我可以看到它正在移动键被释放(键向上)前。

I've tried using preventDefault() and stopImmediatePropagation() in the KeyboardEvent.KEY_DOWN event listener that I also use to change the selected suggestion, but that does not change anything. I checked the carret has not yet moved when KeyboardEvent.KEY_DOWN event is fired, bu visually I can see that it is being move before key is released (key up).

我可以只保存插入位置,然后重置自动对焦的默认行为。但是,使用计时器,将适当涉及一些黑客类code。

I could just save the caret position, and then reset af the default behaviour. But that would properly involve some hack-like code using a timer.

因此​​,没有人知道如何prevent的默认行为?

So does anyone know how to prevent the default behaviour?

推荐答案

您不能prevent它,但你可以扭转它。要做到这一点,你添加到处理器具有不同的优先级相同的事件 - KeyboardEvent.DOWN。一会前文本域的执行,并保存后,选择指数和其他,恢复它们。工作code如下:

You can't prevent it, but you can reverse it. To do that you add to handlers with different priorities to the same event - KeyboardEvent.DOWN. One will execute before the TextField's , and save selection indexes and the other after, restoring them. Working code follows:

    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.ui.Keyboard;

    import mx.controls.TextInput;
    import mx.events.FlexEvent;

    public class FooledTextInput extends TextInput
    {
        private var ssi : int = 0;
        private var sei : int = 0;

        public function FooledTextInput()
        {
            super();

            this.addEventListener(KeyboardEvent.KEY_DOWN, onBeforeKeyDown, false, 10000);
            this.addEventListener(KeyboardEvent.KEY_DOWN, onAfterKeyDown, false, -10000);
        }

        private function onBeforeKeyDown(e : KeyboardEvent) : void
        {
            if (e.keyCode == Keyboard.UP || e.keyCode == Keyboard.DOWN)
            {
                ssi = this.selectionBeginIndex;
                sei = this.selectionEndIndex;
            }   
        } 

        private function onAfterKeyDown(e : KeyboardEvent) : void
        {
            if (e.keyCode == Keyboard.UP || e.keyCode == Keyboard.DOWN)
            {
                this.setSelection(ssi, sei);
            }   
        } 
    }

您可能需要为SSI(选择开始索引)和SEI(选择结束索引)更好的名字,我是懒得找一些。 我认为这个解决方案是基于亚历克斯Harui的文章中,我不记得确切,但他得到了很多很好的Flex的相关的东西在自己的博客。

You might want better names for ssi (selection start index) and sei (selection end index), I was to lazy to find some. I think this solution was based on a post of Alex Harui, I don't remember exactly, but he's got a lot of good Flex related stuff on his blog.

更新:对于Spark的TextInput,preventing不仅是可能的,它是很容易。所有你需要做的就是赶在捕获阶段和停止传播事件。 code:

UPDATE: For the spark TextInput, preventing is not only possible, it is really easy. All you need to do is catch the event in the capture phase and stopping propagation. Code:

package
{
    import flash.events.KeyboardEvent;
    import flash.ui.Keyboard;

    import spark.components.TextInput;

    public class HackedTextInput extends TextInput
    {
        public function HackedTextInput()
        {
            super();
            addEventListener(KeyboardEvent.KEY_DOWN, onBeforeKeyDown, true);
        }

        private function onBeforeKeyDown(e:KeyboardEvent) : void
        {
            if (e.keyCode == Keyboard.UP || e.keyCode == Keyboard.DOWN)
            {
                e.stopImmediatePropagation();
            }   
        }  
    }
}

请注意在的addEventListener调用,它设置为true,以便处理程序被称为捕获阶段的最后一个参数。可悲的是这个解决方案没有为MX的TextInput工作,只为火花之一。

Note the last parameter in the addEventListener call, which is set to true in order for the handler to be called in the capture phase. Sadly this solution doesn't work for the mx TextInput, only for the spark one.