Javascript Angular2 在焦点事件上添加类

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34799667/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 16:51:24  来源:igfitidea点击:

Angular2 on focus event to add class

javascriptjqueryangularangular-directive

提问by Mad Eddie

I'm looking to update an Angular 1 app to Angular 2 and am having an issue with one of my old directives.

我希望将 Angular 1 应用程序更新为 Angular 2,但我的旧指令之一出现问题。

The idea is simple. When an input field is focused a class should be added (md-input-focus) and another be removed (md-input-wrapper). Then this process should be reversed on "blur" event - i.e. focus lost.

这个想法很简单。当输入字段被聚焦时,应该添加一个类(md-input-focus)并删除另一个类(md-input-wrapper)。然后这个过程应该在“模糊”事件上逆转 - 即焦点丢失。

My old directive simply included the lines

我的旧指令只包含这些行

.directive('mdInput',[
    '$timeout',
    function ($timeout) {
        return {
            restrict: 'A',
            scope: {
                ngModel: '='
            },
            link: function (scope, elem, attrs) {
                var $elem = $(elem);
                $elem.on('focus', function() {
                      $elem.closest('.md-input-wrapper').addClass('md-input-focus')
                })
                .on('blur', function() {
                 $(this).closest('.md-input-wrapper').removeClass('md-input-focus');
                })
             }

etc...

等等...

I obviously have the classic start to my directive but have run out of.....skill

我的指令显然有经典的开始,但已经用完了......技能

import {Directive, ElementRef, Renderer, Input} from 'angular2/core';

@Directive({
      selector: '.mdInput',

})

export class MaterialDesignDirective {
      constructor(el: ElementRef, renderer: Renderer) {
           // Insert inciteful code here to do the above
      }
}

Any help would be appreciated.

任何帮助,将不胜感激。

UPDATE:

更新:

The HTML would look like (before the input element was focused):

HTML 看起来像(在输入元素聚焦之前):

<div class="md-input-wrapper">
   <input type="text" class="md-input">
</div>

and then

进而

<div class="md-input-wrapper md-input-focus">
   <input type="text" class="md-input">
</div>

after.

后。

The input element is the only one which can receive a focus event (and therefore the target for the directive) however the parent <div>requires the class addition and removal.

input 元素是唯一可以接收焦点事件(因此也是指令的目标)的元素,但是父元素<div>需要添加和删除类。

Further help

进一步帮助

Please see Plunker for help/explanation- would be great if someone could help

请参阅 Plunker 寻求帮助/解释- 如果有人可以提供帮助,那就太好了

回答by Günter Z?chbauer

Update

更新

@Directive({selector: '.md-input', host: {
  '(focus)': 'setInputFocus(true)',
  '(blur)': 'setInputFocus(false)',
}})
class MaterialDesignDirective {
  MaterialDesignDirective(private _elementRef: ElementRef, private _renderer: Renderer) {}
  setInputFocus(isSet: boolean): void {
    this.renderer.setElementClass(this.elementRef.nativeElement.parentElement, 'md-input-focus', isSet);
  }
}

Original

原来的

This can easily be done without ElementRefand Renderer(what you should strive for in Angular2) by defining host bindings:

这可以通过定义主机绑定轻松完成,无需ElementRefRenderer(您应该在 Angular2 中努力实现的目标):

import {Directive, ElementRef, Renderer, Input} from 'angular2/core';

@Directive({
      selector: '.mdInput',
      host: {
        '(focus)':'_onFocus()',
        '(blur)':'_onBlur()',
        '[class.md-input-focus]':'inputFocusClass'
      }

})

export class MaterialDesignDirective {
      inputFocusClass: bool = false;

      _onFocus() {
        this.inputFocusClass = true;
      }

      _onBlur() {
        this.inputFocusClass = false;
      }
}

or a bit more terse

或者更简洁一点

@Directive({
      selector: '.mdInput',
      host: {
        '(focus)':'_setInputFocus(true)',
        '(blur)':'_setInputFocus(false)',
        '[class.md-input-focus]':'inputFocusClass'
      }

})

export class MaterialDesignDirective {
      inputFocusClass: bool = false;

      _setInputFocus(isFocus:bool) {
        this.inputFocusClass = isFocus;
      }
}

I tried it only in Dart where it works fine. I hope I translated it correctly to TS.

我只在 Dart 中尝试过,效果很好。我希望我把它正确翻译成 TS。

Don't forget to add the class to the directives:of the element where you use the directive.

不要忘记将类添加到directives:使用指令的元素的 。

回答by user1928596

In addition to previous answers, if you don't want to add a directive, for the specific component (you already have a directive for a parent component, you are using Ionic 2 page or something else), you inject the renderer by adding private _renderer: Rendererin the page constructor and update the element using the event target like this:

除了前面的答案之外,如果您不想添加指令,对于特定组件(您已经有了父组件的指令,您正在使用 Ionic 2 页面或其他内容),您可以通过添加private _renderer: Renderer来注入渲染器页面构造函数并使用事件目标更新元素,如下所示:

html:

html:

(dragstart)="dragStart($event)"

TS:

TS:

dragStart(ev){
    this._renderer.setElementClass(ev.target, "myClass", true)
}

Edit: to remove the class just do:

编辑:要删除该类,只需执行以下操作:

dragEnd(ev){
    this._renderer.setElementClass(ev.target, "myClass", false)
}

回答by abahet

If you want to catch the focus / blur events dynamiclly on every input on your component :

如果您想在组件的每个输入上动态捕捉焦点/模糊事件:

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

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements AfterViewInit {
  name = 'Angular focus / blur Events';

  constructor(private el: ElementRef) {
  }

  ngAfterViewInit() {
       // document.getElementsByTagName('input') : to gell all Docuement imputs
       const inputList = [].slice.call((<HTMLElement>this.el.nativeElement).getElementsByTagName('input'));
        inputList.forEach((input: HTMLElement) => {
            input.addEventListener('focus', () => {
                input.setAttribute('placeholder', 'focused');
            });
            input.addEventListener('blur', () => {
                input.removeAttribute('placeholder');
            });
        });
    }
}

Checkout the full code here : https://stackblitz.com/edit/angular-wtwpjr

在此处查看完整代码:https: //stackblitz.com/edit/angular-wtwpjr

回答by Roman Alshehri

The name of the selector has to be inside "[ ]", as shown below

选择器的名字必须在“[]”里面,如下图

@Directive({
  selector: '[.mdInput]',
  host: {
    '(focus)':'_setInputFocus(true)',
    '(blur)':'_setInputFocus(false)',
    '[class.md-input-focus]':'inputFocusClass'
  }
})