angular 2+ 垂直调整 div

angular 2+ vertically resize div

我是 angular2 的新手,我一直在尝试创建一个可调整大小的 div(垂直)。但我无法做到这一点。我尝试使用指令

这是我的指令

import { Directive, HostListener, ElementRef, Input } from '@angular/core';

@Directive({
  selector: '[appNgxResizer]'
})
export class NgxResizerDirective {

  constructor(private el: ElementRef) {
  }

  @HostListener('mousemove', ['$event']) resize(e) {
    this.el.nativeElement.parentNode.style.height = (e.clientY - this.el.nativeElement.parentNode.offsetTop) + 'px';
    event.preventDefault();
  }

  @HostListener('mouseup', ['$event']) stopResize(e) {
    event.preventDefault();
  }
}

这是我尝试过的 stackblitz https://stackblitz.com/edit/angular-text-resizable-q6ddyy

我想点击抓取来调整 div 的大小。像这样 https://jsfiddle.net/zv2ep6eo/.

谢谢。

试试这个:

添加一个变量:

private canResize = false;

在鼠标按下时通过将 canResize 设置为 true 来启用调整大小:

@HostListener('mousedown', ['$event']) enableResize(e) {
    this.canResize = true;
    event.preventDefault();
}

以便您仅在鼠标按下时调整大小:

@HostListener('window:mousemove', ['$event']) resize(e) {
  if (this.canResize) {
    this.el.nativeElement.parentNode.style.height = (e.clientY - this.el.nativeElement.parentNode.offsetTop) + 'px';
  }
  event.preventDefault();
}

在鼠标松开时将 canResize 设置为 false 以禁用调整大小:

@HostListener('window:mouseup', ['$event']) stopResize(e) {
    this.canResize = false;
    event.preventDefault();
}

另外,看看this

(更新:已创建 stackblitz

我想你错过了保留旧高度值的部分,加上检查 mouseup 上的状态并收听 mousedown。我没有在下面的示例中使用指令,但它会很复杂。

Stackblitz example

打字稿:

  height = 150;
  y = 100;
  oldY = 0;
  grabber = false;

  @HostListener('document:mousemove', ['$event'])
  onMouseMove(event: MouseEvent) {
    if (!this.grabber) {
        return;
    }
    this.resizer(event.clientY - this.oldY);
    this.oldY = event.clientY;
  }

  @HostListener('document:mouseup', ['$event'])
  onMouseUp(event: MouseEvent) {
    this.grabber = false;
  }

  resizer(offsetY: number) {
    this.height += offsetY;
  }


  @HostListener('document:mousedown', ['$event'])
  onMouseDown(event: MouseEvent) {
    this.grabber = true;
    this.oldY = event.clientY;
    event.preventDefault();
  }

HTML

<div class="textarea" [style.height.px]='height' contenteditable="true" >
  this is a text area
  <div class="grabber"></div>  
</div>

使用@Vega 的答案 - 指令

import { Directive, HostListener, ElementRef, OnInit } from '@angular/core';

@Directive({
  selector: '[resizer]'
})
export class NgxResizerDirective implements OnInit {

  height: number;
  oldY = 0;
  grabber = false;

  constructor(private el: ElementRef) { }

  @HostListener('document:mousemove', ['$event'])
  onMouseMove(event: MouseEvent) {

    if (!this.grabber) {
      return;
    }

    this.resizer(event.clientY - this.oldY);
    this.oldY = event.clientY;
  }

  @HostListener('document:mouseup', ['$event'])
  onMouseUp(event: MouseEvent) {
    this.grabber = false;
  }

  resizer(offsetY: number) {
    this.height += offsetY;
    this.el.nativeElement.parentNode.style.height = this.height + "px";
  }

  @HostListener('mousedown', ['$event']) onResize(event: MouseEvent, resizer?: Function) {
    this.grabber = true;
    this.oldY = event.clientY;
    event.preventDefault();
  }

  ngOnInit() {
    this.height = parseInt(this.el.nativeElement.parentNode.offsetHeight);
  }

}

HTML

<div class="textarea" contenteditable="true">
  this is a text area
  <div class="grabber" resizer contenteditable="false" ></div>
</div>

我发现这个库非常有用且易于使用:angular-split

用法如下所示(以下示例取自左侧导航菜单的应用程序组件,右侧呈现单个 components/pages - 如果您喜欢垂直导航菜单,这是一个高度使用的用例.)

<as-split direction="horizontal" style="height: 1000px;">
        <as-split-area size="15">
            <app-nav-menu></app-nav-menu>
        </as-split-area>
        <as-split-area size="85">
            <div class="col-12 col-lg-9 body-content">
                <router-outlet></router-outlet>
            </div>
        </as-split-area>
</as-split>

我对@Sibiraj 和@Vega 的回答做了一点改进。 建议解决方案的主要问题是性能:

@HostListener('document:mousemove', ['$event'])
  onMouseMove(event: MouseEvent) {

    if (!this.grabber) {
      return;
    }

    this.resizer(event.clientY - this.oldY);
    this.oldY = event.clientY;
  }

您必须了解 @HostListener('document:mousemove', ['$event']) 会在您的文档上每次鼠标移动时触发,您可以避免在 mousedown 事件之后添加 mousemove 侦听器并在 [=19] 之后取消它=] 事件。请看我的版本:

import {Directive, ElementRef, HostListener, OnDestroy, OnInit} from '@angular/core';
import {fromEvent, Subject} from 'rxjs';
import {takeUntil} from 'rxjs/operators';

@Directive({
  selector: '[resizer]'
})
export class ResizeDirective implements OnInit, OnDestroy {
    height: number;
    oldY = 0;
    grabber = false;
    destroy$ = new Subject();

    constructor(private el: ElementRef) { }

    ngOnInit() {
        this.height = parseInt(this.el.nativeElement.parentNode.offsetHeight, 10);
    }

    @HostListener('document:mouseup', ['$event'])
    onMouseUp(): void {
        this.grabber = false;
        this.destroy$.next();
    }

    @HostListener('mousedown', ['$event']) onResize(event: MouseEvent, resizerCallback?: Function) {
        this.grabber = true;
        this.oldY = event.clientY;
        event.preventDefault();

        this.addMouseMoveListener();
    }

    resizer(offsetY: number): void {
        this.height += offsetY;
        this.el.nativeElement.parentNode.style.height = this.height + 'px';
    }

    addMouseMoveListener(): void {
        fromEvent(document, 'mousemove')
            .pipe(takeUntil(this.destroy$))
            .subscribe(this.mouseMoveCallback.bind(this));
    }

    mouseMoveCallback(event: MouseEvent): void {
        if (!this.grabber) {
            return;
        }

        this.resizer(event.clientY - this.oldY);
        this.oldY = event.clientY;
    }

    ngOnDestroy() {
        this.destroy$.next();
    }

}