# List对象的相关方法
List对象的方法调用暂**不支持**链式语法。
## 目录
- [Demo](#demo)
- [创建列表](#创建列表) `new()`
- [删除列表](#删除列表) `del()`
- [切换到某个列表](#切换到某个列表) `use()`
- [向当前列表中添加弹幕](#向当前列表中添加弹幕) `addDm()`
- [dmData](#dmdata)
- [time](#time)
- [示例](#示例)
- [从当前列表中移除弹幕](#从当前列表中移除弹幕) `delDm()`
- [danmakuSerial](#danmakuserial)
- [根据时刻从当前列表中创建弹幕](#根据时刻从当前列表中创建弹幕) `tick()`
- [调整当前列表的时刻不确定度](#调整当前列表的时刻不确定度) `uncertainty()`
- [图解](#图解)
- [顾虑](#顾虑)
- [建议](#建议)
- [往当前列表中载入一批弹幕](#往当前列表中载入一批弹幕) `load()`
- [danmakuArr](#danmakuarr)
- [使用技巧:载入弹幕js文件](#使用技巧载入弹幕js文件)
- [使用技巧:载入弹幕json文件](#使用技巧载入弹幕json文件)
- [导出当前列表](#导出当前列表) `export()`
- [outputName](#outputname)
- [fileType](#filetype)
- [download](#download)
- [展示:导出的js文件内容](#展示导出的js文件内容)
## Demo
见[示例:弹幕-时刻列表](https://ndanmaku.xbottle.top/#弹幕-时刻列表)
## 创建列表
```javascript
danmaku.list.new(listName)
```
- `listName` - 待创建的列表名称
要使用列表,需要先创建列表,不是嘛!
------
## 删除列表
```javascript
danmaku.list.del(listName)
```
- `listName` - 待删除的列表名称
列表不要了就用这个方法删了罢
------
## 切换到某个列表
```javascript
danmaku.list.use(listName)
```
- `listName` - 待切换的列表名称
**接下来的方法**都必须要**先通过此方法“切换到”列表中**才能使用。
借用一下数据库管理系统的`use`
------
## 向当前列表中添加弹幕
```javascript
danmaku.list.addDm(dmData, time)
```
- `dmData` - 待添加的弹幕数据
- `time` - 弹幕出现的时刻,单位为毫秒(ms)
- **返回值**:弹幕**在列表中**的**代号**`danmakuSerial`
> 使用前提:使用`use()`方法切换到了列表中
### dmData
取值为**一个对象**,包含一条弹幕的数据。
示例对象:
```javascript
{
text: '', // 弹幕内容
reset_styles: false, // 是否在设置样式前重置样式,否则继承之前的样式
styles: {...}, // 弹幕样式
created: null // 同danmaku.create的创建后回调created()
callback: null // 同danmaku.create的弹幕结束后回调callback()
}
```
### time
取值为**一个整数**,单位为**毫秒(ms)**,代表弹幕出现的时刻。
### 示例
比如在`955ms`处插入一条蓝色弹幕,并在创建该弹幕时重置样式:
```javascript
danmaku.list.addDm({
text: '这是一条逆向滚动弹幕',
reset_styles: true,
styles: {
color: 'blue'
}
}, 955);
```
------
## 从当前列表中移除弹幕
```javascript
danmaku.list.delDm(danmakuSerial)
```
- `danmakuSerial` - 待从**当前列表**中移除的弹幕代号
- **返回值**:布尔值`true`/`false`,代表是/否移除成功
> 使用前提:使用`use()`方法切换到了列表中
### danmakuSerial
取值为**一个字符串**,代表**当前列表中**某条弹幕的代号。
**弹幕代号**在用`addDm()`方法添加弹幕时会返回。
------
## 根据时刻从当前列表中创建弹幕
```javascript
danmaku.list.tick(time)
```
- `time` - 需要检查的时刻,单位为毫秒(ms)
> 使用前提:使用`use()`方法切换到了列表中
光在列表中添加了弹幕,该怎么让这些弹幕被创建出来捏?这就不得不提到咱们的`tick()`方法了!
通过调用该方法,程序会在列表中寻找在`time`时刻(或附近)的弹幕,并**创建**命中的弹幕。
为什么还加了一小句“或附近”呢?看接下来这一个方法吧!
-------
## 调整当前列表的时刻不确定度
```javascript
danmaku.list.uncertainty(time)
```
- `time` - 不确定时间段,单位为毫秒(ms)
- **每一个列表**的**默认时刻不确定度**为 `200ms`
> 使用前提:使用`use()`方法切换到了列表中
上面的`tick()`方法会搜索某一时刻的弹幕并加以创建。
实际使用中,媒体的时间精确度可能**达不到毫秒级**,但弹幕时刻精确到了毫秒,这就导致如果`tick(媒体时刻)`的话,可能有些弹幕不会被创建出来。
因此引入了时刻不确定度。
### 图解
```javascript
danmaku.list.uncertainty(0);
danmaku.list.tick(200);
```
这个时候**仅搜索**在时刻`200ms`处的弹幕,图中的**弹幕2**会被创建:

------
```javascript
danmaku.list.uncertainty(45);
danmaku.list.tick(200);
```
这个时候搜索的是**一段时间范围内**( `200 ± 45 ms` )的弹幕,图中的**弹幕2**、**弹幕3**会被创建:

-------
### 顾虑
骚年,你是否在顾虑这种情况?

我超,两次`tick`过近了,但`uncertainty`指定的弹幕搜索范围比较大,两次的搜索范围发送了**重叠**!这怎么整?
哈哈,实际上咱考虑到了这点,发生重叠情况的时候会**自动调整搜索范围**,所以不用担心的啦~

### 建议
在网页媒体中使用弹幕列表时,你可能会用到`timeupdate`事件:
```javascript
video.addEventListener('timeupdate', function(e) {
let currentMilli = Math.round(e.target.currentTime * 1000);
danmaku.list.tick(currentMilli);
});
```
按照[MDN文档](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/timeupdate_event)的说明,基本上能保证该事件每秒被触发`4-66`次,大概每两次事件触发之间是`15ms-250ms`的时间间隔。
因此咱建议在这里设置时刻不确定度为`300ms-500ms`,这样能最大程度上保证弹幕的创建。
如果`timeupdate`实在不确定性太大了,你其实可以使用`setInterval()`来**定时**`tick()`,只不过需要手动处理**暂停/播放**相关的事件。
-----
## 往当前列表中载入一批弹幕
```javascript
danmaku.list.load(danmakuArr)
```
- `danmakuArr` - 待载入的包含弹幕数据的数组
- **返回值**:布尔值`true`/`false`,代表是/否载入成功
> 使用前提:使用`use()`方法切换到了列表中
当弹幕数量很大时,使用`addDm()`方法一条一条地添加弹幕到列表中实在是太麻烦了,因此有了这个`load()`方法,将一批弹幕一次性添加到列表中。
### danmakuArr
取值为**一个数组**,这个数组的每一个元素是一个**弹幕数据对象**。
弹幕数据对象示例如下:
```javascript
{
time: 0, // 弹幕出现的时刻,单位为毫秒(ms)
text: '', // 弹幕内容
reset_styles: false, // 是否在设置样式前重置样式,否则继承之前的样式
styles: {...}, // 弹幕样式
created: null // 同danmaku.create的创建后回调created()
callback: null // 同danmaku.create的弹幕结束后回调callback()
}
```
`danmakuArr`数组示例:
```javascript
[
{
time: 1098,
text: '这是一条无描边,底部悬停的绿色弹幕',
styles: {
color: 'green',
life: 4000,
outline: false,
type: 'bottom',
'bottom_space': 30
}
},
{
time: 1072,
text: '这是一条随机黄色弹幕',
styles: {
color: 'yellow',
life: 4000,
outline: false,
type: 'random',
'bottom_space': 2
}
}
]
```
### 使用技巧:载入弹幕js文件
创建一个JavaScript文件作为**弹幕数据文件**,可以这样写:
```javascript
const myList = [ // 这里咱就放两条测试弹幕
{
time: 2000,
text: '测试弹幕1'
},
{
time: 1002,
text: '测试弹幕2'
}
]
```
将这个文件命名为`myList.js`。
在页面中载入这个文件中的弹幕数据,可以这样写:
```html