角度2+垂直调整div

时间:2017-09-26 08:05:10

标签: javascript css angular typescript angular2-directives

我是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();
  }
}

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

的stackblitz

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

感谢。

5 个答案:

答案 0 :(得分:2)

我想你错过了保持高度旧值的部分,并检查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>

答案 1 :(得分:2)

使用@ 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>

答案 2 :(得分:1)

试试这个:

添加变量:

private canResize = false;

在mousedown上通过将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

答案 3 :(得分:1)

我改善了@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'])将在文档上的每次鼠标移动时触发,您可以避免在mousemove事件之后添加mousedown侦听器,并在'mouseup'事件之后取消它。请查看我的版本:

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();
    }

}

答案 4 :(得分:0)

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

用法如下所示(以下示例取自左侧导航菜单的应用程序组件,右侧呈现了单个组件/页面-如果您喜欢垂直导航菜单,这是一个非常常用的用例。)

<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>