【问题标题】:angular2 manually firing click event on particular elementangular2 在特定元素上手动触发点击事件
【发布时间】:2016-08-06 23:23:06
【问题描述】:

我正在尝试以编程方式触发元素上的单击事件(或任何其他事件),换句话说,我想知道 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 上的点击事件

【问题讨论】:

  • 如果您按照@akshay-khale stackoverflow.com/a/41675017/344029 的以下回答(添加变量&lt;input #imgFile 后),您只需要imgFile.click() 而不是showImageBrowseDlg()

标签: angular angular2-forms


【解决方案1】:

Angular4

代替

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

使用

    this.fileInput.nativeElement.dispatchEvent(event);

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

Angular2

使用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/en-US/docs/Web/API/EventTarget/dispatchEvent

【讨论】:

  • this.fileInput.nativeElement.click() 似乎也有效。
  • @lbrahim 是正确的。当时强烈建议避免访问nativeElement 的属性或方法,而改用Renderer。我认为这最近发生了很大变化,直接 DOM 访问现在很好,但它不适用于服务器端渲染和 WebWorkers。
  • @AralRoca 然后使用@ViewChildren('fileInput') QueryList&lt;ElementRef&gt;; 另见stackoverflow.com/questions/32693061/…
  • 我对此并不完全确定,也没有看到官方文档提到它,但据我记得在一些 GitHub 问题中提到了它。我还想记住一些文档示例已更新以删除渲染器并使用直接 DOM 访问。我的印象是,如果您不打算使用服务器端渲染或网络工作者,那么这只是一个繁琐的限制,很多开发人员并不关心这一点,这是他们消除使之成为强大的规则。
  • @ManuChadha 为什么要使用 jquery?当 Angular 和 jquery 认为它们都完全控制 FOM 时,可能会导致问题。 jquery 最近变得不那么重要了,因为浏览器之间的差异要小得多,并且大多数人完全放弃了对旧浏览器的支持。
【解决方案2】:

我也想要类似的功能,我有一个带有display:none文件输入控件和一个我想触发点击事件按钮控件 > 单击按钮时的文件输入控件,下面是执行此操作的代码

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

就这么简单,而且运行完美......

【讨论】:

  • 在文本字段中按回车键后,我正是使用它来单击按钮:&lt;input #name type="text" (keyup.enter)="addBtn.click()"&gt; &lt;button #addBtn (click)="add(name.value)" type="button"&gt;Add&lt;/button&gt;
【解决方案3】:

这对我有用:

<button #loginButton ...

在控制器内部:

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

【讨论】:

    【解决方案4】:

    要获得对 ion-input 之类的本地引用,请使用此

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

    然后

    this.fileInput.nativeElement.querySelector('input').click()
    

    【讨论】:

      【解决方案5】:

      Günter Zö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]);
        }
      

      在我的情况下,如果不是,我会收到“caught RangeError: Maximum call stack size exceeded”错误。 (我有一个点击时触发的 div 卡和里面的输入文件)

      【讨论】:

      • 您还可以将“bubbles”键设置为 false,以防止事件在 dom 树上冒泡
      【解决方案6】:

      如果你想像这样模仿点击 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();
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-07
        • 1970-01-01
        • 2018-11-23
        • 1970-01-01
        相关资源
        最近更新 更多