angular / angular/components

bug(drag-drop): Auto-scroll can break while dragging between drop lists

Ouverte
#19,241 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub
area: cdk/drag-drop P3
Langage dominant
TypeScript
Étoiles
25k
Forks
6.8k
Merge moyen
1 j 8 h
PR mergées (30 j)
91

Description

Auto-scroll functionality can break if an item is dropped in a list while auto-scrolling, then attempting to perform that same auto-scroll sequence.

[ng-run demo](https://ng-run.com/edit/m0ciJ24IuzdCDaV31wVR)

1) Drag an item from one list to another while auto-scrolling.
2) While auto-scroll is still taking place (this is important), drop the item into the new list.
3) Scroll back to the original list and try the exact same sequence again with another item.

Auto-scrolling will stop once the item has entered the second drop list.

GIF demonstration:

![GIF](https://user-images.githubusercontent.com/23387905/80869228-467ad380-8c6d-11ea-9765-b3c64cf9a314.gif)

***Problem***

Auto-scroll properties (`_scrollNode`, `_verticalScrollDirection`, `horizontalScrollDirection`) are not being cleared when auto-scroll is stopped.

Upon the second auto-scroll sequence entering the bottom drop list, the following conditional statement (noted with the `HERE` comment) returns false because all the old (non-cleared) properties are the same as the current ones...yet auto-scroll should still be triggered.

```ts
/**
* Checks whether the user's pointer is close to the edges of either the
* viewport or the drop list and starts the auto-scroll sequence.
* @param pointerX User's pointer position along the x axis.
* @param pointerY User's pointer position along the y axis.
*/
_startScrollingIfNecessary(pointerX: number, pointerY: number) {
if (this.autoScrollDisabled) {
return;
}

let scrollNode: HTMLElement | Window | undefined;
let verticalScrollDirection = AutoScrollVerticalDirection.NONE;
let horizontalScrollDirection = AutoScrollHorizontalDirection.NONE;

//...

// <-- HERE-->
if (scrollNode && (verticalScrollDirection !== this._verticalScrollDirection ||
horizontalScrollDirection !== this._horizontalScrollDirection ||
scrollNode !== this._scrollNode)) {
this._verticalScrollDirection = verticalScrollDirection;
this._horizontalScrollDirection = horizontalScrollDirection;
this._scrollNode = scrollNode;

if ((verticalScrollDirection || horizontalScrollDirection) && scrollNode) {
this._ngZone.runOutsideAngular(this._startScrollInterval);
} else {
this._stopScrolling();
}
}
}
```

#### Environment

- Angular:
- CDK/Material: 9.2.2
- Browser(s):
- Operating System (e.g. Windows, macOS, Ubuntu):

Guide de contribution

Ouvrir le guide de contribution

Piste de recherche

Commencez par la méthode _startScrollingIfNecessary présentée dans l’issue et suivez son interaction avec _stopScrolling et les propriétés de l’état de défilement automatique. Reproduisez la séquence dans la démo ng-run liée, puis vérifiez que la répétition de la séquence de glisser-déposer redémarre le défilement automatique après qu’un élément a été déposé pendant le défilement.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
angular, typescript
Domaine
frontend
Type d'issue
Bug
Difficulté
3/5
Temps estimé
1-2 jours
Activité
À l'abandon
Clarté
Clairement spécifiée
Accessibilité débutants
45/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.