如何通过选择器访问 DOM 元素

Posted

技术标签:

【中文标题】如何通过选择器访问 DOM 元素【英文标题】:How I can access DOM element by selector 【发布时间】:2017-05-11 00:04:36 【问题描述】:

在 Angular2 中,有没有办法通过它的选择器而不是在模板中而是在整个 DOM 中获取元素?

【问题讨论】:

***.com/questions/40759325/… 【参考方案1】:

不建议直接在 angular2 中访问 DOM,因为你绕过了 Angular2 渲染器

您可以使用其他 angular 2 功能来执行此操作,例如:添加对此元素的引用。

看看这个问题,它可以帮助你: How to get dom element in angular 2

【讨论】:

很高兴知道这类事情,但多年来,在我编写了所有 Angular 代码之后,我已经有了这样的心态:如果它简单、可读、有效并且可以经测试,则没有任何问题。 Angular 让做一些非常简单的事情变得非常痛苦,如果一个普通的 ol' JS 解决方案在实用性上更胜一筹并且满足您的需要,那么就使用它。毕竟,Angular 只是一种工具,它不是最终的圣经。【参考方案2】:

当然,window.document.querySelectorwindow.document.querySelectorAll

【讨论】:

投反对票:我看不出这个答案如何按照 OP 的要求提供“Angular2-way” OP 没有说“An Angular 2 Way”。他只是说“在Angular 2中”。请注意,这已经是什么......几乎一年的公认答案? OP赞成它。说真的……更好的消磨时间的方式。 我认为 Angular 2 方式更适合上下文,如果我使用 Angular,很明显我需要使用“TheFrameworkIuse”方式。 我认为这应该留给 OP,他支持答案。 “显而易见”通常比个人认为的更为相对。 @TimConsolazio 仅带有 angular 标签的问题意味着它应该是一个 angular 答案【参考方案3】:

我将把它作为另一个答案发布,而不是编辑旧答案,因为恕我直言,这两种方法都很有用。但这绝对是一个更加“Angularish”的。

有两种 Angularish-2 方法来获取对模板 DOM 元素的引用; ElementRef 和 ViewChild。可能还有更多,但这是随处提到的两个。

ElementRef 可能最好避免。显然,它使您面临潜在的 XSS 攻击。文档周围有各种红色的“小心”。

所以我选择了一个非常有效的东西,那就是 ViewChild。

我的模板:

<input #myinput type="text" />

注意看起来很奇怪的#myInput。它用作 ID,但不是普通的“DOM id=”。我认为这可以解决唯一 ID 问题,以及使用空 CSS 类代替 ID 标记元素的丑陋黑客攻击。

在您的代码中:注意我使用的是没有注释的 ES6。但要获得相同的效果,您将使用 @ViewChild 注释。它在 TS 中有很好的文档(根本不在 ES6 中,我花了很长时间才把它拼凑起来)。

仅供参考,我必须想出一个干净的方法来做到这一点,因为我想实现一个 RxJS 流来做一些去抖动和诸如此类的事情。

import  Component, ngOnInit, ViewChild  from '@angular/core';

class HomeComponent 
    constructor( ) 

    ngOnInit ( ) 
        // .nativeElement console.log's out to what you'd expect.
        var inputBox = this.myInputRef.nativeElement;
        // left this in to demonstrate it works as plain ol' DOM elem,
        // if it didn't, this wouldn't work.
        var source = Rx.Observable.fromEvent(inputBox, 'click');
        ...
    


HomeComponent.annotations = [
    new Component ( 
       templateUrl: './views/home/home.component.html',
       queries:  'myInputRef': new ViewChild ( 'myinput' ) 
     )
];
export  HomeComponent 

像魅力一样工作。大约是时候我们在 Angular 中有类似的东西了。 JQLite 真的从来没有削减过它。

【讨论】:

ViewChild 与 ElementRef 完全相同 天啊...不,不是。甚至没有接近(如果是他们不会打扰另一个)。 是的,它只是获取相同对象的不同方式。 XSS 警告与通过 nativeElement 方法直接将元素更新/插入到 DOM 中有关——因为 Angular 不会将其“清理”运算符应用于更新的元素。不过这有点超卖了,因为很少有人会使用用户提供的 HTML 来更新 DOM。 Renderer2 和 ViewChild/ViewContent 系统在许多方面都非常有限。如果您查看源代码,Angular 中的大多数 npm 模块/库都可以访问文档/窗口 例如github.com/angular/material2/blob/master/src/cdk/overlay/… 您还会在该链接中注意到 _methodName 用于他们的私有方法,这是我们也不应该做的事情之一(根据样式约定)。最佳实践和实用性之间的区别:-)【参考方案4】:

今天有一种使用 Document 查询元素的“Angular”方式:

import  Inject  from '@angular/core';
import  DOCUMENT  from '@angular/common';

class DOMService 
  constructor(@Inject(DOCUMENT) private document) 

  getElementsByClass(clazz: string): HTMLCollection[] 
    return this.document.getElementsByClassName(clazz);
  

尤其是服务器端渲染功能,例如不建议直接访问window (window &amp;&amp; window.document..)。如果你也在操作元素,你应该考虑使用 Angulars Renderer2

如果您只需要访问当前组件中的元素,您可以使用@ViewChildElementRef 功能。

【讨论】:

以上是关于如何通过选择器访问 DOM 元素的主要内容,如果未能解决你的问题,请参考以下文章

jQuery 选择器

jQuery 选择器

Jquery 库详解 ---3.2 以CSS 选择器访问DOM元素

jQuery小节

关于jQuery的选择器

js-DOM中基础选择器的整理