admin管理员组文章数量:1307166
I'm trying to implement a drag and drop file upload in angular 8, heavily inspired by this article, and this one.
I cant get any of the drag events to fire. I've checked that the DragDropDirective
is imported by using mouseenter
methods in the same directive, which launch correctly, i also see that style that i added is correctly applied.
I've been banging my head against this all day, what am i missing?
Edit: This works with files from a Files explorer, but not with files from the desktop. Using Ubuntu 19.
// ponent.html
<section appDragDrop class="panel" id="dropzone-wrapper" (onFileDropped)="uploadFile($event)">
<input type="file" #fileInput (change)="uploadFile($event.target.files)" accept=".json" hidden>
<label for="dropzone">
<span>
drag and drop here.
</span>
</label>
</section>
import { Directive, Output, Input, EventEmitter, HostBinding, HostListener, ElementRef } from '@angular/core';
@Directive({
selector: '[appDragDrop]'
})
export class DragDropDirective {
el: ElementRef
constructor(el: ElementRef) {
el.nativeElement.style.backgroundColor = 'yellow';
}
// Working fine
@HostListener('mouseenter') onMouseEnter() {
console.log('mouse entering')
}
// Working fine
@HostListener('mouseleave') onMouseLeave() {
console.log('mouse leaving')
}
// --- Not working ---
@HostListener('dragover', ['$event']) onDragOver(evt) {
console.log('A')
}
// --- Not working ---
@HostListener('dragleave', ['$event']) public onDragLeave(evt) {
console.log('B')
}
// --- Not working ---
@HostListener('drop', ['$event']) public ondrop(evt) {
console.log('C')
}
}
NOTE
Drag and drop doesn't seem to work from screen to screen on linux, you need to test with files from the same screen.
I'm trying to implement a drag and drop file upload in angular 8, heavily inspired by this article, and this one.
I cant get any of the drag events to fire. I've checked that the DragDropDirective
is imported by using mouseenter
methods in the same directive, which launch correctly, i also see that style that i added is correctly applied.
I've been banging my head against this all day, what am i missing?
Edit: This works with files from a Files explorer, but not with files from the desktop. Using Ubuntu 19.
// ponent.html
<section appDragDrop class="panel" id="dropzone-wrapper" (onFileDropped)="uploadFile($event)">
<input type="file" #fileInput (change)="uploadFile($event.target.files)" accept=".json" hidden>
<label for="dropzone">
<span>
drag and drop here.
</span>
</label>
</section>
import { Directive, Output, Input, EventEmitter, HostBinding, HostListener, ElementRef } from '@angular/core';
@Directive({
selector: '[appDragDrop]'
})
export class DragDropDirective {
el: ElementRef
constructor(el: ElementRef) {
el.nativeElement.style.backgroundColor = 'yellow';
}
// Working fine
@HostListener('mouseenter') onMouseEnter() {
console.log('mouse entering')
}
// Working fine
@HostListener('mouseleave') onMouseLeave() {
console.log('mouse leaving')
}
// --- Not working ---
@HostListener('dragover', ['$event']) onDragOver(evt) {
console.log('A')
}
// --- Not working ---
@HostListener('dragleave', ['$event']) public onDragLeave(evt) {
console.log('B')
}
// --- Not working ---
@HostListener('drop', ['$event']) public ondrop(evt) {
console.log('C')
}
}
NOTE
Drag and drop doesn't seem to work from screen to screen on linux, you need to test with files from the same screen.
Share Improve this question edited Apr 2, 2021 at 10:55 Preston asked Mar 6, 2020 at 13:49 PrestonPreston 8,19711 gold badges63 silver badges94 bronze badges4 Answers
Reset to default 2The code you have provided works fine: https://stackblitz./edit/angular-ayht81?embed=1&file=src/app/drag-drop.directive.ts
Drop event
Drop will not fire unless you prevent the default behavior on over:
@HostListener("dragover", ["$event"]) onDragOver(evt) {
evt.preventDefault()
console.log("A");
}
Proof of work:
Better late than never, but it works for me:
@HostListener("dragover", ["$event"]) onDragOver(event: any) {
event.preventDefault()
}
@HostListener('drop', ['$event']) onDrop(event: any): boolean {
console.log("drop", event)
return false
}
The answer to this issue is usually that you've set preventDefault()
and or stopPropagation()
elsewhere which is messing with these listeners everywhere on the page.
Here is my go-to directive:
Pay attention to preventBodyDrop
.
import { Directive, EventEmitter, HostBinding, HostListener, Input, Output } from '@angular/core';
// Angular Drag and Drop File
//
// Add this directive to an element to turn it into a dropzone
// for drag and drop of files.
// Example:
//
// <div dropzone (dropzone)="onDrop($event)"></div>
//
// Any files dropped onto the region are then
// returned as an array of file objects.
// Which in TypeScript is `Array<File>`
@Directive({
selector: '[libDropzone]',
standalone: true
})
export class DropZoneDirective {
// The directive emits a `fileDrop` event
// with the list of files dropped on the element
// as a JS array of `File` objects.
@Output('libDropzone') fileDrop = new EventEmitter<Array<File>>();
// Disable dropping on the body of the document.
// This prevents the browser from loading the dropped files
// using it's default behaviour if the user misses the drop zone.
// Set this input to false if you want the browser default behaviour.
@Input() preventBodyDrop = true;
// The `drop-zone-active` class is applied to the host
// element when a drag is currently over the target.
@HostBinding('class.dragging-over') draggingOver = false;
@HostBinding('class.dropped') dropped = false;
// default list of allowed file extensions
@Input() allowedExts?: ['jpg', 'jpeg', 'png', 'gif']; // iOS HVEC?
// DRAG AND DROP EVENTS - https://developer.mozilla/en-US/docs/Web/API/HTML_Drag_and_Drop_API
@HostListener('drop', ['$event'])
onDrop(event: DragEvent) {
event.preventDefault();
this.draggingOver = false;
const { dataTransfer } = event;
if (dataTransfer?.items) {
const files: any[] = [];
for (let i = 0; i < dataTransfer.items.length; i++) {
// If dropped items aren't files, reject them
// TODO: confirm supported image file type (allowedExts)
// optionally allow allowedExts to override allowed extensions
if (dataTransfer.items[i].kind === 'file') {
files.push(dataTransfer.items[i].getAsFile());
}
}
dataTransfer.items.clear();
if (!!files?.length) this.fileDrop.emit(files);
} else {
const files = dataTransfer?.files;
dataTransfer?.clearData();
if (!!files?.length) this.fileDrop.emit(Array.from(files));
}
this.dropped = true;
setTimeout(() => {
this.dropped = false;
}, 3000);
}
@HostListener('dragover', ['$event'])
onDragOver(event: DragEvent) {
this.draggingOver = true;
}
@HostListener('dragleave', ['$event'])
onDragLeave(event: DragEvent) {
this.draggingOver = false;
}
// disable native browser file drop on <body>
@HostListener('body:dragover', ['$event'])
onBodyDragOver(event: DragEvent) {
if (this.preventBodyDrop) {
event.preventDefault();
event.stopPropagation();
}
}
@HostListener('body:drop', ['$event'])
onBodyDrop(event: DragEvent) {
if (this.preventBodyDrop) {
event.preventDefault();
}
}
}
If you want to use Drag and Drop event for file upload you should use window:dragenter
event listener. This event starts file drag into window and when drag event started then dragover
, dragleave
and drop
will work as well.
Example:
// missing listener which detects that something was dragged into window area
@HostListener('window:dragenter', ['$event'])
onWindowDragEnter(event: any): void {
event.preventDefault();
event.stopPropagation();
}
@HostListener('dragover', ['$event'])
onDragOver(event: any): void {
event.preventDefault();
event.stopPropagation();
// ...
}
@HostListener('dragleave', ['$event'])
public onDragLeave(event: any): void {
event.preventDefault();
event.stopPropagation();
// ...
}
@HostListener('drop', ['$event'])
public onDrop(event: any): void {
event.preventDefault();
event.stopPropagation();
// ...
}
However solution wasn't tested on Ubuntu
本文标签: javascriptAngular 8 drag drop dragover dragleave events not firingStack Overflow
版权声明:本文标题:javascript - Angular 8 drag drop dragover dragleave events not firing - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741834069a2400109.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论