在输入模糊时隐藏元素,但单击元素时除外

问题描述 投票:0回答:1

我有以下用例:

input,只要有焦点,输入旁边应显示一个弹出窗口。因此,当input具有焦点时,用户可以键入input或使用弹出窗口选择内容。

用户完成操作后,可以通过单击在其他位置或通过按Tab键并集中关注下一个元素。但是,如果他单击弹出窗口内的按钮,则该弹出窗口应保持不变打开,输入应保持焦点,以便用户可以继续打字。

我所遇到的问题是输入在弹出窗口中处理(click)之前对其进行了角度处理(模糊)。这意味着当用户在弹出窗口中单击,输入失去焦点,它被隐藏,然后用户的点击将不再被处理。

我已将问题设为stackblitz-demo

这是源代码:

app.component.html

<h1>Hello</h1>
<p>
    Type 'one', 'two' or 'three' to change number or select a number
    from popup.
    <br>
    <input type="checkbox" [(ngModel)]="hideHelperOnBlur" /> Hide
    helper on blur (if this is set, then the buttons in the popup don't work
    but if this is not set, the popup doesn't close if the input looses
    focus -> how can I get both? The buttons to work but the popup still
    closing on blur?)
</p>
    Your number: {{selectedNumber}}
<p>
Change number:
<input [ngModel]="formattedNumber" (ngModelChange)="newNumberTyped($event)" (focus)="helperVisible = true"
    (blur)="processBlur()" #mainInput />

<div *ngIf="helperVisible">
    <button *ngFor="let number of numbers" (click)="selectNumber(number.raw)">{{number.formatted}} </button>
</div>

app.component.ts

import { Component, ViewChild, ElementRef } from '@angular/core';

@Component({
    selector: 'my-app',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})
export class AppComponent {
    name = 'Angular';
    formattedNumber: string = 'three';
    selectedNumber: number = 3;
    helperVisible: boolean = false;
    numbers: any[] = [
        { raw: 1, formatted: 'one' },
        { raw: 2, formatted: 'two' },
        { raw: 3, formatted: 'three' }
    ];
    @ViewChild('mainInput', { static: false })
    mainInput: ElementRef;
    hideHelperOnBlur: boolean;

    newNumberTyped(newFormattedNumber: string) {
        this.numbers.forEach((number) => {
            if (newFormattedNumber == number.formatted) {
                this.formattedNumber = newFormattedNumber;
                this.selectedNumber = number.raw;
            }
        });
    }

    selectNumber(newRawNumber: number) {
        this.numbers.forEach((number) => {
            if (newRawNumber == number.raw) {
                this.formattedNumber = number.formatted;
                this.selectedNumber = newRawNumber;
            }
        });
        this.mainInput.nativeElement.focus();
    }

    processBlur() {
        if (this.hideHelperOnBlur) {
            this.helperVisible = false;
        }
    }
}

我期望以下行为:

  • 当输入获得焦点时,弹出窗口可见
  • [当用户单击页面之外的任何地方时,弹出窗口或输入,弹出窗口关闭
  • 当用户在输入聚焦时按Tab键时,输入失去焦点,弹出窗口关闭
  • 当用户单击弹出窗口中的按钮时,将选择该数字

我似乎只能获得第二,第三或第四有效的标准(请参见演示中的复选框)。

我已经尝试过的:

  • 将@HostListener与focusin,focusout或focus一起使用,或(blur)=“ someFunction(event)找出哪个元素具有新焦点检查该元素是在弹出框中还是在输入中->此似乎不起作用,因为在焦点事件发生时还没有明确谁获得了新的关注点
  • 使用超时,以便角度已经完成处理超时结束时单击事件->这似乎正常但有效超时是一个非常笨拙的解决方案,可能会轻易中断

有人有解决方案吗?

javascript angular events focus blur
1个回答
0
投票

更多是Java脚本。 blur事件发生在click事件之前。 click事件仅在释放鼠标按钮后发生。

您可以在此处使用mousedown事件来发挥自己的优势。 mousedown事件发生在blur事件之前。只需在弹出按钮的preventDefault上调用mousedown,即可防止input失去焦点。这也将解决以下问题:单击弹出式窗口中的按钮时,input闪烁,因此您可以在this.mainInput.nativeElement.focus();功能中摆脱selectNumber

<button *ngFor="let number of numbers" (mousedown)="$event.preventDefault()" (click)="selectNumber(number.raw)">{{number.formatted}}</button>

这里是StackBlitz上的有效示例。

© www.soinside.com 2019 - 2024. All rights reserved.