I'm working in Angular 7 trying to create a drag and drop file upload component. I have it working below.
public stopPreventAndSetClass(b: boolean, event: any): void {
if (event.target === this.enterTarget) {
this.draggedOverTable = b;
}
console.log(event.target);
this.stopAndPrevent(event);
}
public stopAndPrevent($event: any): void {
event.preventDefault();
event.stopPropagation();
}
<div class="document-container"
(drop)="saveFiles($event); stopPreventAndSetClass(false, $event)"
(dragenter)="enterTarget = $event.target; stopPreventAndSetClass(true, $event)"
(dragover)="stopAndPrevent($event);"
(dragleave)="stopPreventAndSetClass(false, $event)"
[ngClass]="{'showDropContainerBorder': draggedOverTable}">
<!-- An Angular Material table of uploaded files sits here. So think many child elements. -->
</div>
My problem is that the performance on this is awful (~4 second lag time between drop and saveFiles() running) because change detection is running for every dragover
and dragleave
event fired. After doing a good amount of research, I found that the best solution is supposedly to remove the dragover
event from the ngzone which will prevent the change detection from firing. From here: https://github.com/angular/angular/pull/21681
A very easy way of doing this seems to be (dragover.nozone)="stopAndPrevent($event)"
. This does fix the performance issue, but it also no longer works, as the browser reverts back to using its default behavior (loading file in browser) ignoring the event.preventDefault();
. Does anyone know of a better way to do this or know how to fix the performance issue I'm running into here?
Found a solution. Blacklisting dragover events from zone.js by following https://github.com/JiaLiPassion/blacklist/blob/master/src/index.html and adding
<script>
var targets = [window, Document, HTMLBodyElement, HTMLElement];
__Zone_ignore_on_properties = [];
targets.forEach(function (target) {
__Zone_ignore_on_properties.push({
target: target,
ignoreProperties: ['dragover']
});
});
__zone_symbol__BLACK_LISTED_EVENTS = ['dragover'];
__Zone_disable_requestAnimationFrame = true;
</script>
to my index.html