import {Meta} from '@storybook/addon-docs/blocks'

<Meta title='@dxtmisha/vi/functional-basic/# Quản lý sự kiện'/>

# Quản lý sự kiện

Lớp `EventItem` là một wrapper nâng cao để quản lý trình nghe sự kiện trên các phần tử DOM hoặc đối tượng `window`. Nó đơn giản hóa toàn bộ vòng đời sự kiện, cung cấp khả năng tự động giám sát sự tồn tại của phần tử trong DOM và bao gồm các tối ưu hóa tích hợp cho các sự kiện tần suất cao.

```javascript
import { EventItem } from '@dxtmisha/functional-basic'

// 1. Khởi tạo
const event = new EventItem('.my-button', 'click', () => {
  console.log('Đã click vào nút!')
})

// 2. Quản lý vòng đời
event.start()  // Bắt đầu nghe
event.stop()   // Dừng nghe
event.toggle(true) // Chuyển đổi trạng thái
```

## Giám sát phần tử

Một trong những tính năng chính của `EventItem` là tự động hủy kích hoạt sự kiện nếu phần tử mục tiêu (hoặc phần tử điều khiển) bị xóa khỏi DOM. Điều này ngăn ngừa rò rỉ bộ nhớ và lỗi trong các giao diện động.

```javascript
// Sự kiện sẽ tự động dừng nếu phần tử .my-button biến mất khỏi DOM
const event = new EventItem('.my-button', 'scroll', handler)
event.start()
```

## Tối ưu hóa hiệu suất

Lớp này bao gồm các cơ chế tối ưu hóa tích hợp cho các sự kiện nặng như thay đổi kích thước cửa sổ hoặc đồng bộ hóa cuộn.

### Kiểu `resize`
Sử dụng `ResizeObserver` thay vì sự kiện `resize` tiêu chuẩn, cho phép bạn theo dõi sự thay đổi kích thước của một phần tử cụ thể, không chỉ toàn bộ cửa sổ.

```javascript
const resizeEvent = new EventItem('.container', 'resize', (entry) => {
  console.log('Chiều rộng mới:', entry.contentRect.width)
})
```

### Kiểu `scroll-sync`
Tối ưu hóa việc xử lý cuộn qua `requestAnimationFrame`, ngăn chặn các cuộc gọi handler dư thừa và giảm tải CPU.

```javascript
const scrollEvent = new EventItem(window, 'scroll-sync', () => {
  // Thực thi mượt mà nhất có thể
})
```

## Kích hoạt sự kiện thủ công

Bạn có thể kích hoạt sự kiện trên phần tử mục tiêu một cách thủ công bằng phương thức `dispatch`. Điều này hữu ích để mô phỏng các hành động của người dùng bằng mã.

```javascript
// Mô phỏng một cú click
event.dispatch()

// Truyền thêm dữ liệu (detail)
const customEvent = new EventItem(window, 'my-event', (e, detail) => {
  console.log('Dữ liệu:', detail)
})
customEvent.dispatch({ id: 123 })
```
