angular2手动触发特定元素上的click事件


81

我试图以编程方式在元素上触发click事件(或任何其他事件),换句话说,我想知道与angular2中jQuery .trigger()方法提供的功能相似。

有内置的方法可以做到这一点吗?.....如果没有,请建议我该怎么做

考虑以下代码片段

<form [ngFormModel]="imgUploadFrm"
          (ngSubmit)="onSubmit(imgUploadFrm)">
        <br>
        <div class="input-field">
            <input type="file" id="imgFile" (click)="onChange($event)" >
        </div>
        <button id="btnAdd" type="submit" (click)="showImageBrowseDlg()" )>Add Picture</button>
 </form>

在这里,当用户单击btnAdd时,它将触发imgFile上的click事件


您只需要imgFile.click()代替showImageBrowseDlg()@ akshay-khale stackoverflow.com/a/41675017/344029(添加变量之后<input #imgFile)的以下答案即可
DJDaveMark

Answers:


182

角度4

代替

    this.renderer.invokeElementMethod(
        this.fileInput.nativeElement, 'dispatchEvent', [event]);

使用

    this.fileInput.nativeElement.dispatchEvent(event);

因为invokeElementMethod它将不再是渲染器的一部分。

角度2

ViewChild与模板变量一起使用以获取对文件输入的引用,然后使用Renderer调用dispatchEvent以触​​发事件:

import { Component, Renderer, ElementRef, ViewChild } from '@angular/core';
@Component({
  ...
  template: `
...
<input #fileInput type="file" id="imgFile" (click)="onChange($event)" >
...`
})
class MyComponent {
  @ViewChild('fileInput') fileInput:ElementRef;

  constructor(private renderer:Renderer) {}

  showImageBrowseDlg() {
    // from http://stackoverflow.com/a/32010791/217408
    let event = new MouseEvent('click', {bubbles: true});
    this.renderer.invokeElementMethod(
        this.fileInput.nativeElement, 'dispatchEvent', [event]);
  }
}

更新资料

由于Angular团队不再鼓励直接DOM访问,因此也可以使用更简单的代码

this.fileInput.nativeElement.click()

另请参阅https://developer.mozilla.org/zh-CN/docs/Web/API/EventTarget/dispatchEvent


10
this.fileInput.nativeElement.click()似乎也可以。
lbrahim

3
@lbrahim是正确的。当时强烈建议避免访问属性或方法,nativeElement而应Renderer改为使用。我认为最近这发生了很大变化,现在可以直接进行DOM访问了,但不适用于服务器端渲染和WebWorkers。
君特Zöchbauer

1
然后@AralRoca使用@ViewChildren('fileInput') QueryList<ElementRef>;又见stackoverflow.com/questions/32693061/...
君特Zöchbauer

1
我对此并不完全确定,也没有看到官方文档提到它,但是据我所记得,在某些GitHub问题中曾提到它。我还想记住,一些文档示例已更新,以删除渲染器并使用直接DOM访问。如果您不打算使用服务器端渲染或网络工作人员,则给我的印象是,这只是一个繁琐的局限,很多开发人员都不在乎,这是他们摆脱了使强大的规则。
君特Zöchbauer

1
@ManuChadha为什么完全使用jquery?当Angular和jquery认为它们都完全掌握了FOM时,可能会导致问题。jQuery最近变得越来越不相关,因为大多数浏览器之间的差异很小,并且对旧浏览器的支持已被大多数人完全放弃。
君特Zöchbauer

27

我也希望类似的功能,在那里我有一个文件输入控制display:none按钮控制,我想触发点击事件文件输入控制,当我按一下按钮,下面是代码这样做

<input type="button" (click)="fileInput.click()" class="btn btn-primary" value="Add From File">
<input type="file" style="display:none;" #fileInput/>

如此简单,并且可以正常工作...


1
在文本字段中按Enter键后,我正是以此来单击按钮:<input #name type="text" (keyup.enter)="addBtn.click()"> <button #addBtn (click)="add(name.value)" type="button">Add</button>
DJDaveMark

4

这对我有用:

<button #loginButton ...

在控制器内部:

@ViewChild('loginButton') loginButton;
...
this.loginButton.getNativeElement().click();

谢谢,兄弟。它与ionic3一样具有魅力。:)
DwlRathod

这不适用于Angular 7+
davejoem

2

GünterZöchbauer的答案是正确的。只需考虑添加以下行:

showImageBrowseDlg() {
    // from http://stackoverflow.com/a/32010791/217408
    let event = new MouseEvent('click', {bubbles: true});
    event.stopPropagation();
    this.renderer.invokeElementMethod(
        this.fileInput.nativeElement, 'dispatchEvent', [event]);
  }

在我的情况下,如果没有,我将收到“捕获的RangeError:超出最大调用堆栈大小”错误。(我在单击时触发了div卡,并在其中输入了文件)


1
您也可以将“ bubbles”键设置为false,以防止事件使dom树冒泡
ChicoDelaBarrio

2

如果要模仿,请单击DOM元素,如下所示:

<a (click)="showLogin($event)">login</a>

并在页面上显示以下内容:

<li ngbDropdown>
    <a ngbDropdownToggle id="login-menu">
        ...
    </a>
 </li>

您的功能component.ts应如下所示:

showLogin(event) {
   event.stopPropagation();
   document.getElementById('login-menu').click();
}

0

ion-input使用此方法获取对诸如ry的本地引用

@ViewChild('fileInput', { read: ElementRef }) fileInput: ElementRef;

然后

this.fileInput.nativeElement.querySelector('input').click()
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.