angular4 防二次重复点击
  • 监听click事件,
  • 默认三秒钟内的点击事件触发第一次的点击事件,也可以通过throttleTime自定义时间 只触发第一次
/**
 * <div  (throttleClick)="goExceptionReport()" [throttleTime]="5000">throttleClick 5 S</div>
 * <div  (throttleClick)="goExceptionReport()">throttleClick default</div>
 * <div tappable (throttleClick)="goExceptionReport()">throttleClick default with tappable</div>
 */
import { Directive, EventEmitter, HostListener, Input, OnDestroy, OnInit, Output } from "@angular/core";
import { Subject } from "rxjs/Subject";
import { Subscription } from "rxjs/Subscription";

@Directive( {
  selector: "[throttleClick]",
} )
export class ThrottleClickDirective implements OnInit, OnDestroy {
  @Input() public throttleTime = 3000;
  @Output() public throttleClick = new EventEmitter();
  private clicks = new Subject<any>();
  private subscription: Subscription;

  constructor() {}

  ngOnInit() {
    // 拦截点击事件只传递第一次点击事件的处理操作交给parent来处理
    this.subscription = this.clicks
      .throttleTime( this.throttleTime )
      .subscribe(( e ) => this.throttleClick.emit( e ) );
  }

  ngOnDestroy() {
    // 取消订阅
    this.subscription.unsubscribe();
  }

  // HostListener这个装饰器可以监听directive作用的dom元素的click事件,第二个参数$event告诉Angular传递点击事件到directive中去;
  @HostListener( "click", [ "$event" ] )
  clickEvent( event: MouseEvent ) {
    // 防止事件继续向parent component中传递
    event.preventDefault();
    event.stopPropagation();
    // 这里使用subject的.next来传递点击事件,然后使用rxjs的函数操作符throttleTime来处理延时事件,在指定事件内只处理第一次操作,调用emit传递点击事件的操作到parent中去继续处理;
    this.clicks.next( event );
  }
}
  • 默认三秒钟内的点击事件触发最后一次的点击事件,也可以通过debounceTime自定义时间 只触发最后一次
    import { Directive, EventEmitter, HostListener, OnInit, Output, Input } from '@angular/core';  
    import { Subject } from 'rxjs/Subject';  
    import { debounceTime } from 'rxjs/operators';  
    import {Subscription} from 'rxjs/Subscription';  

    @Directive({  
        selector: '[appDebounceClick]'  
    })  
    export class DebounceClickDirective implements OnInit {  
        @Input() debounceTime = 500;  
        @Output() debounceClick = new EventEmitter();  
        private clicks = new Subject();  
        private subscription: Subscription;  

        constructor() { }  

        ngOnInit() {  
            // 拦截点击事件然后延迟这些点击事件的执行,直到一段时间内最后一次点击,最后把事件的处理操作交给parent来处理
            this.subscription = this.clicks.pipe(  
                debounceTime(this.debounceTime)  
            ).subscribe(e => this.debounceClick.emit(e));  
        }  

        ngOnDestroy() {  
            this.subscription.unsubscribe();  
        }  

        @HostListener('click', ['$event'])  
        clickEvent(event) {  
            event.preventDefault();  
            event.stopPropagation();  
            this.clicks.next(event);  
        }  
    }
JSRUN notes