javascript - 输入模糊时隐藏弹出窗口,除非单击弹出窗口

标签 javascript angular events focus blur

我有以下用例:
有一个input并且只要有焦点,就应该在输入旁边显示一个弹出窗口。所以虽然input有焦点,用户可以输入 input或使用弹出窗口选择内容。
用户完成后,他可以通过单击来取消对元素的关注
其他地方或通过按 Tab 键并聚焦下一个元素。
但是,如果他单击弹出窗口内的按钮,则弹出窗口应该保持不变
打开并且输入应该保持专注,以便用户可以继续
打字。
我遇到的问题是在处理 (click) 之前对输入进行 Angular 处理(模糊)在弹出窗口中。这意味着当用户
单击弹出窗口,输入失去焦点,被隐藏,然后
将不再处理用户的点击。
我做了一个 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;
        }
    }
}
我期望以下行为:
  • 当输入获得焦点时,弹出窗口可见
  • 当用户点击页面上任何不是
    弹出或输入,弹出关闭
  • 当用户在输入焦点时按下选项卡时,输入
    失去焦点,弹出窗口关闭
  • 当用户单击弹出窗口中的按钮时,该号码将被选中

  • 我似乎只能得到第二个和第三个或第四个
    工作标准(请参阅演示中的复选框)。
    我已经尝试过的:
  • 将@HostListener 与focusin、focusout 或focus 一起使用或
    (blur)="someFunction(event) 找出哪个元素有新的焦点
    检查该元素是否在弹出窗口或输入中 -> this
    似乎不起作用,因为在 focusout-event 时它还没有
    明确谁获得新焦点
  • 使用超时以便 angular 已经完成处理
    超时结束时的单击事件-> 这似乎有效但有效
    超时是一个非常笨拙的解决方案,可能很容易中断

  • 有没有人有办法解决吗?

    最佳答案

    这更像是一个 Javascript 的东西。 blur事件发生在 click 之前事件。 click事件仅在释放鼠标按钮后发生。

    您可以使用 mousedown在这里举办事件对您有利。 mousedown事件发生在 blur 之前事件。只需调用 preventDefaultmousedown在弹出按钮中防止 input从失去焦点。这也将解决您的 input 的问题。单击弹出窗口中的按钮时会闪烁,这样您就可以摆脱 this.mainInput.nativeElement.focus();在您的 selectNumber功能。

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

    这是 StackBlitz 上的一个工作示例.

    关于javascript - 输入模糊时隐藏弹出窗口,除非单击弹出窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58147275/

    相关文章:

    javascript - js数学答案验证

    javascript - 为什么 colspan 不是 Angular 2 中已知的原生属性?

    javascript - Handlebars - 预编译模板中的脚本不运行

    html - Angular : Cannot locate two p-col-6 side by side in PrimeNG FlexGrid

    javascript - 在 Angular 2 中调用函数时在 HTML 中创建一个 div

    jquery - 删除子项的事件处理程序

    javascript - 使用 Javascript 在 Sharepoint 上打开嵌入的 Excel 工作簿

    angular - 为什么 Asp net Core 会为我的 Angular Spa dist 文件的请求返回 index.html?

    ios - 如何获取 UITextField 光标更改事件?

    angular - 使用 angular2 配置 Hammerjs 事件