【问题标题】:Angular accept file drag n drop from computer into divAngular接受文件从计算机拖放到div
【发布时间】:2020-11-21 08:29:15
【问题描述】:

我正在尝试让拖放在 Angular 中工作。

现在我有这个,我在这里找到的:

.ts

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

@Component({
  selector: 'drag-root',
  templateUrl: './drag.component.html',
  styleUrls: ['./drag.component.css']
})
export class AppComponent {

  allowDrop(ev) {
    ev.preventDefault();
  }

  drag(ev) {
    ev.dataTransfer.setData("text", ev.target.id);
  }

  drop(ev) {
    ev.preventDefault();
    var data = ev.dataTransfer.getData("text");
    ev.target.appendChild(document.getElementById(data));
  }
}

HTML

<h2>Drag and Drop</h2>
<div  id="div1" 
      (drop)="drop($event)" 
      (dragover)="allowDrop($event)">

      <img 
      src="https://images.pexels.com/photos/658687/pexels-photo-658687.jpeg?auto=compress&cs=tinysrgb&h=350" 
      draggable="true" 
      (dragstart)="drag($event)" 
      id="drag1"
      width="88" 
      height="31">
</div>

<div id="div2" 
  (drop)="drop($event)" 
  (dragover)="allowDrop($event)">
</div>

上面的代码只是让我从一个 div 拖放到另一个 div 中。

我需要做的是能够将文件从我的计算机拖放到组件中的 div 中并获取文件名。

我该怎么做?

【问题讨论】:

标签: angular


【解决方案1】:

我不久前整理的基本文件放置组件:

file-drop.component.ts

import { Component, ElementRef, ViewChild, EventEmitter, Output } from '@angular/core';

/**
 * Basic component to provide file drag & drop (and click) functionality
 * for uploading files using HTML file API.
 * https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/File_drag_and_drop
 *
 * Note if looking at the debug console in FF and find the drop dataTransfer
 * value to be null - that's only a debug display issue with FF.
 * https://stackoverflow.com/a/60305243/1585218
 */
@Component({
  selector: 'app-file-drop',
  templateUrl: './file-drop.component.html',
  styleUrls: ['./file-drop.component.scss']
})
export class FileDropComponent {
  private _isDragging: boolean;

  constructor() { }

  @ViewChild('fileSelector') public fileSelector: ElementRef;
  @Output() public selectedFiles = new EventEmitter<File[]>();

  public get isDragging(): boolean { return this._isDragging; }

  public onDrop(event: any): void {
    // Stop browser opening the file
    event.preventDefault();
    this._isDragging = false;

    const result = [];
    if (event.dataTransfer.items) {
      // Use DataTransferItemList interface to access the file(s)
      for (const item of event.dataTransfer.items) {
        if (item.kind !== 'file') {
          return;
        }
        result.push(item.getAsFile());
      }
    } else {
      // Use DataTransfer interface to access the file(s)
      for (const file of event.dataTransfer.files) {
        result.push(file);
      }
    }

    this.emitFiles(result);
  }

  public onFilesSelected(files: any[]): void {
    if (files == undefined || files.length === 0) {
      return;
    }

    const result = [];
    for (const file of files) {
      result.push(file);
    }
    
    this.fileSelector.nativeElement.value = ''; // required to trigger (change) if user immediately uploads same named file 
    this.emitFiles(result);
  }

  public onDragOver(event: any): void {
    // Stop browser opening the file
    event.preventDefault();
    this._isDragging = true;
  }

  public stopDrag(event: any): void {
    this._isDragging = false;
    event.preventDefault();
    event.stopPropagation();
  }


  private emitFiles(files: File[]): void {
    this.selectedFiles.emit(files);
  }
}

文件-drop.component.html

<div class="component-container"
  [class.hovering]="isDragging"
  (click)="fileSelector.click()"
  (drop)="onDrop($event)"
  (dragover)="onDragOver($event)"
  (dragleave)="stopDrag($event)"
  (dragend)="stopDrag($event)">

  <div class="icon"><i class="fas fa-cloud-upload-alt"></i></div>
  <div class="text">Drag &amp; drop or click</div>
  <input #fileSelector type="file" multiple (change)="onFilesSelected($event.target.files)" hidden>
</div>

文件-drop.component.scss

.component-container {
  text-align: center;
  padding: 1em;
  width: 100%;
  height: 100%;
}
.component-container:hover,
.hovering {
  cursor: pointer;
  background-image: -webkit-linear-gradient(135deg,#F6F6F6 25%,transparent 25%,transparent 50%,#F6F6F6 50%,#F6F6F6 75%,transparent 75%,transparent);
  animation: stripes 2s linear infinite;
  background-size: 30px 30px;
  background-color: #fff;
}

.icon {
  font-size: 1.5em;
}
.text {
  font-size: 0.8em;
}
.icon, .text {
  margin: auto;
}

@-webkit-keyframes stripes {
  from {
    background-position: 0 0; }
  to {
    background-position: 60px 30px; } }

@keyframes stripes {
  from {
    background-position: 0 0; }
  to {
    background-position: 60px 30px; } }

基本用法:

<app-file-drop (selectedFiles)="onFilesSelected($event)"></app-file-drop>


...


public onFilesSelected(files: File[]): void {
    for (const file of files) {
      console.log('File:', file);
    }
  }

【讨论】:

    猜你喜欢
    • 2011-09-06
    • 1970-01-01
    • 2012-12-12
    • 1970-01-01
    • 2012-10-19
    • 1970-01-01
    • 2021-07-16
    • 2023-03-11
    • 1970-01-01
    相关资源
    最近更新 更多