# Drag Event A drag event is triggered when a component is dragged. > **NOTE** > > The APIs of this module are supported since API version 8. Updates will be marked with a superscript to indicate their earliest API version. ## Events | Name | Bubbling Supported| Description | | ------------------------------------------------------------ | -------- | ------------------------------------------------------------ | | onDragStart(event: (event?: [DragEvent](#dragevent), extraParams?: string) => [CustomBuilder](ts-types.md#custombuilder8) \| [DragItemInfo](#dragiteminfo)) | No | Triggered when the component bound to the event is dragged for the first time.
- **event**: information about the drag event, including the coordinates of the item that is being dragged.
- **extraParams**: additional information about the drag event. For details, see **[extraParams](#extraparams)**.
Return value: object being dragged, which is used for prompts displayed when the object is dragged.
A drag event can be triggered by a 500 ms long press. If the duration of a long-press gesture is set to less than or equal to 500 ms, the callback for the long-press gesture takes precedence. Otherwise, the callback for the drag event takes precedence.| | onDragEnter(event: (event?: [DragEvent](#dragevent), extraParams?: string) => void) | No | Triggered when the dragged item enters a valid drop target.
- **event**: information about the drag event, including the coordinates of the item that is being dragged.
- **extraParams**: additional information about the drag event. For details, see **[extraParams](#extraparams)**.
This event is valid only when a listener for the **onDrop** event is enabled.| | onDragMove(event: (event?: [DragEvent](#dragevent), extraParams?: string) => void) | No | Triggered when the dragged item moves in a valid drop target.
- **event**: information about the drag event, including the coordinates of the item that is being dragged.
- **extraParams**: additional information about the drag event. For details, see **[extraParams](#extraparams)**.
This event is valid only when a listener for the **onDrop** event is enabled.| | onDragLeave(event: (event?: [DragEvent](#dragevent), extraParams?: string) => void) | No | Triggered when the dragged item leaves a valid drop target.
- **event**: information about the drag event, including the coordinates of the item that is being dragged.
- **extraParams**: additional information about the drag event. For details, see **[extraParams](#extraparams)**.
This event is valid only when a listener for the **onDrop** event is enabled.| | onDrop(event: (event?: [DragEvent](#dragevent), extraParams?: string) => void) | No | Triggered when the dragged item is dropped on a valid drop target.
- **event**: information about the drag event, including the coordinates of the item that is being dragged.
- **extraParams**: additional information about the drag event. For details, see **[extraParams](#extraparams)**.| ## DragItemInfo | Name | Type | Mandatory | Description | | --------- | ---------------------------------------- | ---- | --------------------------------- | | pixelMap | [PixelMap](../apis/js-apis-image.md#pixelmap7) | No | Image to be displayed during dragging. | | builder | [CustomBuilder](ts-types.md#custombuilder8) | No | Custom component to display during dragging. If **pixelMap** is set, this attribute is ignored.| | extraInfo | string | No | Extra information of the dragged item. | ## extraParams Provides additional information required for dragging an item. **extraParams** is a string converted from a JSON object. You can obtain the following attributes using the JSON object converted from **Json.parse**. | Name | Type | Description | | ------------- | ------ | ---------------------------------------- | | selectedIndex | number | Index of the dragged item in the parent container. The value of **selectedindex** starts from **0**.
This attribute is valid only in the drag event of the **\** component.| | insertIndex | number | Index of the element into which the dragged item is dropped in the **List** component. The value of **insertIndex** starts from **0**.
This attribute is valid only in the drag event of the **\** component.| ## DragEvent | Name | Type | Description | | ------ | ------ | ---------------- | | getX() | number | X-coordinate of the drag position relative to the upper left corner of the screen, in vp.| | getY() | number | Y-coordinate of the drag position relative to the upper left corner of the screen, in vp.| ## Example ### Example 1 ```ts @Observed class ClassA { public name: string public bol: boolean constructor(name: string, bol: boolean) { this.name = name this.bol = bol } } @Extend(Text) function textStyle() { .width('25%') .height(35) .fontSize(16) .textAlign(TextAlign.Center) .backgroundColor(0xAFEEEE) } @Entry @Component struct DragExample { @State arr: ClassA[] = [new ClassA('A', true), new ClassA('B', true), new ClassA('C', true)] @State dragIndex: number = 0 changeIndex(index1: number, index2: number) {// Exchange the array position. [this.arr[index1], this.arr[index2]] = [this.arr[index2], this.arr[index1]]; } build() { Column() { Row({ space: 15 }) { List({ space: 20 }) { ForEach(this.arr, (item, index) => { ListItem() { Column() { Child({ a: this.arr[index] }) } .onTouch((event: TouchEvent) => { if (event.type === TouchType.Down) { this.dragIndex = index // Obtain the index of the current dragged child component. console.info('onTouch' + this.dragIndex) } }) } }) } .listDirection(Axis.Horizontal) .onDrop((event: DragEvent, extraParams: string) => { // The component bound to this event can be used as the drop target. When the dragging stops within the component scope, the callback is triggered. let jsonString = JSON.parse(extraParams); this.changeIndex(this.dragIndex, jsonString.insertIndex) }) }.padding({ top: 10, bottom: 10 }).margin(10) }.width('100%').height('100%').padding({ top: 20 }).margin({ top: 20 }) } } @Component struct Child { @ObjectLink a: ClassA @Builder pixelMapBuilder() { Column() { Text(this.a.name) .width('50%') .height(60) .fontSize(16) .borderRadius(10) .textAlign(TextAlign.Center) .backgroundColor(Color.Yellow) } } build() { Column() { Text(this.a.name) .textStyle() .visibility(this.a.bol ? Visibility.Visible : Visibility.None) .onDragStart(() => { // The callback is triggered when the component bound to this event is dragged for the first time. this.a.bol = false // Control the visibility. return this.pixelMapBuilder() // Set the image displayed during dragging. }) .onTouch((event: TouchEvent) => { if (event.type === TouchType.Up) { this.a.bol = true } }) Text('') .width('25%') .height(35) .fontSize(16) .textAlign(TextAlign.Center) .border({ width: 5, color: 'red' }) .visibility(!this.a.bol ? Visibility.Visible : Visibility.None) } } } ``` ![drag-drop](figures/drag-drop.gif) ### Example 2 ```ts // xxx.ets @Extend(Text) function textStyle () { .width('25%') .height(35) .fontSize(16) .textAlign(TextAlign.Center) .backgroundColor(0xAFEEEE) } @Entry @Component struct DragExample { @State numbers: string[] = ['one', 'two', 'three', 'four', 'five', 'six'] @State text: string = '' @State bool: boolean = true @State eventType: string = '' @State appleVisible: Visibility = Visibility.Visible @State orangeVisible: Visibility = Visibility.Visible @State bananaVisible: Visibility = Visibility.Visible private dragList: string[] = ['apple', 'orange', 'banana'] @State fruitVisible: Visibility[] = [Visibility.Visible, Visibility.Visible, Visibility.Visible] @State idx: number = 0 // Customize the content displayed during dragging. @Builder pixelMapBuilder() { Column() { Text(this.text) .width('50%') .height(60) .fontSize(16) .borderRadius(10) .textAlign(TextAlign.Center) .backgroundColor(Color.Yellow) } } build() { Column() { Text('There are three Text elements here') .fontSize(12) .fontColor(0xCCCCCC) .width('90%') .textAlign(TextAlign.Start) .margin(5) Row({ space: 15 }) { ForEach(this.dragList, (item, index) => { Text(item) .textStyle() .visibility(this.fruitVisible[index]) .onDragStart(() => { this.bool = true this.text = item this.fruitVisible[index] = Visibility.None return this.pixelMapBuilder }) .onTouch((event: TouchEvent) => { if (event.type === TouchType.Down) { this.eventType = 'Down' this.idx = index } if (event.type === TouchType.Up) { this.eventType = 'Up' if (this.bool) { this.fruitVisible[index] = Visibility.Visible } } }) }) }.padding({ top: 10, bottom: 10 }).margin(10) Text('This is a List element') .fontSize(12) .fontColor(0xCCCCCC) .width('90%') .textAlign(TextAlign.Start) .margin(15) List({ space: 20 }) { ForEach(this.numbers, (item) => { ListItem() { Text(item) .width('100%') .height(80) .fontSize(16) .borderRadius(10) .textAlign(TextAlign.Center) .backgroundColor(0xAFEEEE) } }, item => item) } .editMode(true) .height('50%') .width('90%') .border({ width: 1 }) .padding(15) .divider({ strokeWidth: 2, color: 0xFFFFFF, startMargin: 20, endMargin: 20 }) .onDragEnter((event: DragEvent, extraParams: string) => { console.log('List onDragEnter, ' + extraParams + 'X:' + event.getX() + 'Y:' + event.getY()) }) .onDragMove((event: DragEvent, extraParams: string) => { console.log('List onDragMove, ' + extraParams + 'X:' + event.getX() + 'Y:' + event.getY()) }) .onDragLeave((event: DragEvent, extraParams: string) => { console.log('List onDragLeave, ' + extraParams + 'X:' + event.getX() + 'Y:' + event.getY()) }) .onDrop((event: DragEvent, extraParams: string) => { let jsonString = JSON.parse(extraParams); if (this.bool) { // Insert an element using the splice method. this.numbers.splice(jsonString.insertIndex, 0, this.text) this.bool = false } this.fruitVisible[this.idx] = Visibility.None }) }.width('100%').height('100%').padding({ top: 20 }).margin({ top: 20 }) } } ``` ![en-us_image_0000001252667389](figures/en-us_image_0000001252667389.gif)