Detect Ctrl + C and Ctrl + V in an input from brow

2019-05-11 06:38发布

I am using the direct following and I do not detect the copy and paste with the keys inside the input, would someone know how? Thank you!

export class OnlyNumberDirective {
    // Allow decimal numbers. The \, is only allowed once to occur
    private regex: RegExp = new RegExp(/[0-9]+(\,[0-9]{0,1}){0,1}$/g);

    // Allow key codes for special events. Reflect :
    // Backspace, tab, end, home
    private specialKeys: Array<string> = [ 'Backspace', 'Tab', 'End', 'Home', 'Delete', 'Del', 'Ctrl', 'ArrowLeft', 'ArrowRight', 'Left', 'Right' ];

    constructor(private el: ElementRef) {
    }

    @HostListener('keydown', [ '$event' ])
    onKeyDown(event: KeyboardEvent): string {
        // Allow Backspace, tab, end, and home keys
        if (this.specialKeys.indexOf(event.key) !== -1) {
            return null;
        }

        // Do not use event.keycode this is deprecated.
        // See: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
        let current: string = this.el.nativeElement.value;
        // We need this because the current value on the DOM element
        // is not yet updated with the value from this event
        let next: string = current.concat(event.key);
        if (next && !String(next).match(this.regex)) {
            event.preventDefault();
            return null;
        } else {
            return next;
        }
    }
}

4条回答
在下西门庆
2楼-- · 2019-05-11 07:28

Angular provides high level API for listening to key press combinations. Check out the following example.

ctrl-keys.directive.ts

import { Directive, Output, EventEmitter, HostListener } from '@angular/core';

@Directive({
  selector: '[ctrlKeys]',
})
export class CtrlKeysDirective  {
  @Output() ctrlV = new EventEmitter();
  @Output() ctrlC = new EventEmitter();

  @HostListener('keydown.control.v') onCtrlV() {
    this.ctrlV.emit();
  }

  @HostListener('keydown.control.c') onCtrlC() {
    this.ctrlC.emit();
  }
}

Usage

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `
  <input ctrlKeys (ctrlV)="onCtrlV()" (ctrlC)="onCtrlC()" >
  `,
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  onCtrlV() {
    console.log('ctrlV pressed')
  }

  onCtrlC() {
    console.log('ctrlC pressed')
  }
}

Live demo

查看更多
做自己的国王
3楼-- · 2019-05-11 07:33

Just add this to any component. When the user performs the key combination Ctrl +s it will print 'Save Performed'

@HostListener('document:keydown.control.s', ['$event']) onKeydownHandler(event: KeyboardEvent) {
    console.log('Save Performed');
    event.preventDefault();
}

If you want Ctrl +v replace the 's' in 'document:keydown.control.s' with 'v'.

查看更多
我命由我不由天
4楼-- · 2019-05-11 07:34

You simply can do who : for information this code manage all mac user who user CMD instead of ctrl

@HostListener('window:keydown',['$event'])
onKeyPress($event: KeyboardEvent) {
    if(($event.ctrlKey || $event.metaKey) && $event.keyCode == 67)
        console.log('CTRL + C');
    if(($event.ctrlKey || $event.metaKey) && $event.keyCode == 86)
        console.log('CTRL +  V');
}

If you want to detect other kind of shortcut :

  • event.ctrlKey
  • event.altKey
  • event.metaKey (Aka Cmd for mac user)

Online sample

--- UPDATE AFTER COMMENT ---

You may can do something like this

  ngOnInit() {
        this.bindKeypressEvent().subscribe(($event: KeyboardEvent) => this.onKeyPress($event));
    }

    onKeyPress($event: KeyboardEvent) {
        if(($event.ctrlKey || $event.metaKey) && $event.keyCode == 67)
            console.log('CTRL + C');
        if(($event.ctrlKey || $event.metaKey) && $event.keyCode == 86)
            console.log('CTRL +  V');
    }

    private bindKeypressEvent(): Observable<KeyboardEvent> {
        const eventsType$ = [
            fromEvent(window, 'keypress'),
            fromEvent(window, 'keydown')
        ];
        // we merge all kind of event as one observable.
        return merge(...eventsType$)
            .pipe(
                // We prevent multiple next by wait 10ms before to next value.
                debounce(() => timer(10)),
                // We map answer to KeyboardEvent, typescript strong typing...
                map(state => (state as KeyboardEvent))
            );
    }

or if is not working, just :

private bindKeypress(): Observable<KeyboardEvent> {
    const typeOfEvent = this.deviceService.getKeybordEvent();
    fromEvent(window, typeOfEvent)
    .pipe(
        // We map answer to KeyboardEvent, typescript strong typing...
        map(state => (state as KeyboardEvent))
    );
}

Where this.deviceService.getKeybordEvent(); is method who return type of event base on User Agent. massive list of user agent can be find here

查看更多
乱世女痞
5楼-- · 2019-05-11 07:34

Instead of monitoring the key events for copy and paste commands, I suggest handling the clipboard events (copy, cut, paste). In addition to taking care of the various shortcuts used on different platforms, it also detects the clipboard operations initiated with the context menu. Please note that the paste event can be cancelled with e.preventDefault(). You can see the code at work in this stackblitz.

@HostListener('copy', ['$event'])
onCopy(e: ClipboardEvent) {
  ...
}

@HostListener('paste', ['$event'])
onPaste(e: ClipboardEvent) {
  let clipboardData = e.clipboardData || window.clipboardData;
  let pastedText = clipboardData.getData('text');
  ...
}
查看更多
登录 后发表回答