<div align="center">
    <img width="150" height="auto" src="http://120.26.44.217:5050/image/logo.png" />
    <h4>纯js封装的聊天框，兼容各大框架适用，适配pc与h5的交互</h4>
    <p align="center">
        <a href="https://www.npmjs.com/package/chatarea">
        <img src="https://img.shields.io/badge/npm-v3.8.0-blue" alt="version" />
        </a>
        <a href="https://www.npmjs.com/package/chatarea">
        <img src="https://img.shields.io/badge/js-44kb-red" alt="size" />
        </a>
        <a href="https://www.npmjs.com/package/chatarea">
        <img src="https://img.shields.io/badge/css-18kb-green" alt="size" />
        </a>
        <a href="https://www.npmjs.com/package/chatarea">
        <img src="https://img.shields.io/badge/License-MIT-yellow" />
        </a>
    </p>
</div>
<h3>
  <a href="http://www.jianfv.top/ChatAreaDoc/" target="_blank">查看使用文档</a>
  <a href="http://www.jianfv.top/chatarea/" target="_blank">查看简易的示例页面</a>
</h3>

### 安装
```
npm i --save chatarea
```
### 基本使用
```javascript
import ChatArea from 'chatarea'
// 引入css样式
import 'chatarea/lib/ChatArea.css'

// 此时页面将你传入的元素生成为一个简单的聊天框,你可以通过元素class修改为你提供的默认样式
const chat = new ChatArea({
  // 注* 当这个元素style属性position未设置为absolute,relative,fixed之一将会默认赋值relative
  elm: document.getElementById('id'), // 从dom上抓取一个元素将其改造
  userList: [ // 当输入@键时弹出人员选择的列表
    {
      id: '1',
      name: '张三',
      avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png',
      pinyin: 'zhang san' // 如已有数据未支持，可以自行下载pinyin-pro以支持该交互效果
    },
    {
      id: '2',
      name: '李四'
    },
    {
      id: '3',
      name: 'jianfv'
    },
    {
      id: '4',
      name: '今晚打老虎'
    }
  ],
  placeholder: '请输入文本框内容', // 输入提示文案
  needCallEvery: true, // 是否需要@所有人功能，默认值为true
  needCallSpace: false, // 是否需要@人员标签后跟随着一个空格，默认值为false
  copyType: ['text', 'image'], // 允许在输入框内粘贴板粘贴的类型 默认值：['text'],
  userProps: { // 人员列表数据结构 转接差异key值
      id: 'id',
      name: 'name',
      avatar: 'avatar',
      pinyin: 'pinyin'
  },
  uploadImage: async (file) => { // 当启用图片粘贴时，可以自定义上传接口，不传则默认将图像资源转为base64
    const res = await this.$api.youUploadFileApi(file)
    // 需要返回img src的地址
    return res.data
  },
  wrapKeyFun: (event) => event.ctrlKey && ['Enter', 'NumpadEnter'].includes(event.code), // 自定义折行 该代码段为默认值
  sendKeyFun: (event) => !event.ctrlKey && ['Enter', 'NumpadEnter'].includes(event.code) // 自定义发送 该代码段为默认值
})
```

### 发送事件 与 获取文本框内容，@人员
```javascript
// 请为实例对象 enterSend 赋值你的自定义方法 当键盘敲击回车时将自动调用这个事件
chat.enterSend = youSendFun = () => {
  // 获取纯文本
  const text1 = chat.richText.innerText // 不推荐 原文本
  const text2 = chat.getText() // 推荐 过滤0宽
  // 获取html
  const html1 = chat.richText.innerHTML // 不推荐 原html
  const html2 = chat.getHtml() // 推荐 过滤0宽并移除@人员标签上无关渲染的属性 极大减少html长度
  // 获取文本中被@到的人员
  const userList = chat.getCallUserList()
  // 在此处执行你对发送消息的处理
  // 渲染历史消息列表的时候可以根据html对应的class 修改其展示效果
}
```

### 实例对象方法
```javascript
// 在@人员选择中 使用↑↓方向健可以切换选中人员 使用 ctrl + enter 进行文本折行

// 获取精简后的文本框dom
chat.getReduceNode()

// 获取输入框文本
chat.getText()

// 获取输入框html
chat.getHtml()

// 获取输入框中@人员对应的数据列表
chat.getCallUserList()

// 往光标处插入html
chat.insertHtml(`<img src="${url}" alt="404" />`) // 光标处插入图片，可以使用该方法插入表情包

// 往光标处插入整体文本
chat.insertText('txt')

// 往光标处插入@人员标签
chat.setUserTag({ id: 'id', name: 'name' })

// 清空输入框方法
chat.clear()
chat.clear('重置文本') // 清空输入框并默认显现文本内容

// 识别文本是否为空 富文本输入框并不能使用传统的 innerHTML 和 innerText 进行判断空值 因为其包含了0宽字符
chat.isEmpty()

// 当需要更新配置项时 可以使用 updateConfig 按需传入即可 每一项都不是非必传
chat.updateConfig({
    copyType: ['text'], // 更新粘贴类型
    userProps: { id: 'userId', name: 'userName' }, // 更新用户数据值索引
    userList: [{ userId: 'NEW1', userName: '新的人员' }], // 更新用户列表数据
    uploadImage: async () => { // 更新粘贴图片回调方法
        return 'img src'
    },
    needCallEvery: false, // 更新是否需要@所有人
    placeholder: '新的提示语', // 更新提示语
    needCallSpace: true, // 更新@人员标签是否需要衔接空格
    wrapKeyFun: (event) => event.shiftKey && ['Enter', 'NumpadEnter'].includes(event.code), // 更新自定义折行
    sendKeyFun: (event) => !event.shiftKey && ['Enter', 'NumpadEnter'].includes(event.code) // 更新自定义发送
})

// 用于页面或组件销毁时卸载在body内挂载的元素并释放实例对象
chat.dispose()
```

### 实例属性说明
```javascript
// 输入框区域的容器元素
chat.richText

// @人员列表（*注：请通过实例方法更新人员，不要直接修改实例属性）
chat.userList

// 输入框区域支持粘贴的类型
chat.copyType // 默认值 ['text', 'image']

// 将用户头像存储缓存容器 [id]:base64
chat.base64Images

// 识别是否为PC端操作，呈现不同的操作交互（*注：H5的交互请用手机去体验，浏览器模拟的H5无法正常的触发事件交互）
chat.isPc

// 一些页面交互dom元素
chat.xxxElm
```

### 问题联系
```
微信：13587774709
QQ：1596170432
```

### 版本更新日志
```
v3.8.0 => H5兼容优化：兼容苹果软键盘中文输入以及@事件
v3.7.8 => 添加域名更新文档访问链接，无代码段更新
v3.7.7 => 粘贴兼容：兼容从其他平台软件copy过来的换行标识为纯\r的特殊兼容
v3.7.6 => 粘贴交互升级：兼容粘贴换行内容
v3.7.5 => bug修复：默认弹窗关闭后 关联一些逻辑优化
v3.7.3 => 新增配置项：needDialog => 是否需要默认的交互弹窗, 默认值为true
          新增私有api: onceSetTag, batchSetTag => 用于处理自定义交互弹窗业务
v3.7.2 => 交互优化：新增删除行自动聚焦滚动
          bug修复：修复如果同一个页面开启多个聊天框存在的兼容问题
v3.7.0 => 交互优化：折行自动滚动到最新的折行段
          说明文档初版开发完毕
v3.6.5 => 代码优化：清空无用的注释代码，初始化逻辑简明修整，部分方法整合调用
          重要更新：增强js仿造复杂性交互，强化用户对输入框一些极端操作的稳定性
v3.6.1 => 废弃对document.execCommand的使用，使用js仿造其交互逻辑提升兼容性
v3.6.0 => 重要更新：新增标签和文本连续选择后一并删除后置的拼接逻辑
          重写方向键盘光标移动逻辑
          兼容QQ浏览器其他一些事件的处理
v3.5.7 => 优化使用方向键盘上下光标逻辑
          新增api：showPCCheckDialog() => 唤起PC@人员多选弹窗
          开放api：showH5Dialog() => 唤起H5@人员弹窗
v3.5.5 => 兼容修复：修复QQ浏览器@标签后中文连拼异常问题
v3.5.3 => bug修复：修复calc不支持大写的PX打包异常问题
v3.5.2 => 新增api：updateConfig(option) => 更新配置项
          新增配置项：needCallSpace => 是否需要@人员标签后跟随着一个空格，默认值为false
          新增配置项：wrapKeyFun(event) => 自定义折行键盘敲击逻辑
          新增配置项：sendKeyFun(event) => 自定义发送键盘敲击逻辑
          交互逻辑修改：当人员列表为空时将不触发@弹窗（之前是弹窗内空数据提示）
          剔除配置项：wrapKey改用更加灵活的方式
v3.5.0 => 初始化样式兼容
          优化@人员弹窗从四个角度淡入的动画
v3.4.7 => 新增配置项：needCallEvery => 是否需要@所有人
          新增配置项：wrapKey => 折行操作键，可选值'ctrlKey' | 'shiftKey' | 'altKey'，默认值ctrlKey
          新增配置项：userProps => 转接差异的用户数据结构
          优化api：clear() => clear(txt)：重置文本并显现传入的文本值
          样式优化：提高弹窗的层级
          交互优化：防止冒泡事件的一些兼容处理
v3.4.3 => 优化输入框粘贴文本处理逻辑
          详细的开发文档正在建设中
v3.4.2 => H5端统一兼容样式：请确保添加<meta>标签写入<meta name="viewport" content="..., initial-scale=1.0, ..." />
          bug修复：修复在敲击中文输法时直接敲击回车键盘时会将中文输入法的分隔符'并接发送
v3.4.0 => 稳定开发版本
v3.3.0 => 新增配置参数：uploadImage(file) => Promise<Stirng|URL>，用于用户在文本框粘贴图片走自定义上传接口并返回图片资源的地址用于展示，不传这个配置参数则默认使用将图片资源转成base64进行展示（这样会使html片段将会很大，不推荐）
          修改配置项copyType的默认值：['text', 'image] => ['text']，现在默认粘贴类型仅允许为文本类型，如需要支持图片类型请修改配置项
          api修改：unLoad(旧) => dispose(新)，在原有卸载元素的逻辑上添加释放实例对象
v3.2.8 => 代码优化
v3.2.7 => 实例化参数拦截: 对用户非法传参的参数值进行拦截提示
v3.2.3 => bug修复: 文本框Cltrl+A全选替换问题
v3.2.2 => 拆分js和css文件
          优化js包的体积 125kb => 37kb
v3.1.0 => 参考pinyin-pro的match方法替换原拼音匹配方式，使其检索方式更人性化
v3.0.7 => 排序逻辑优化
v3.0.6 => tag样式微调
v3.0.5 => markdown优化
v3.0.1 => bug修复：h5弹窗搜索值关闭后未清空问题
v3.0.0 => H5交互版本开发完毕
```
```
v2.3.1 => bug修复：在唤起@弹窗继续输入文本将搜索匹配的人员列表时 使用中文连拼时敲击回车功能丢失问题
v2.3.0 => 新增新的交互功能：在唤起@弹窗继续输入文本将搜索匹配的人员列表
          新增api：setUserTag(user) => 手动在光标处添加传入的人员@标签
          添加css动画
          H5交互基本框架构建,3.0版本将完全开放h5版本的交互
v2.2.0 => 恢复@人员弹窗出现时，禁止键盘输入操作（该版本将放开这个限制）
          部分样式类名修改（预留h5开发）
v2.1.9 => 剔除无用uid属性
          部分方法分离
v2.1.8 => css样式文件细分
          api优化：unLoad同步卸载一些绑定的事件
          dom操作逻辑优化
v2.1.7 => 新增api：unLoad() => 用于页面或组件销毁时卸载在body内挂载的元素
v2.1.6 => 添加滚动样式
v2.1.2 => 优化粘贴板粘贴文本
V2.0.8 => 光标交互扩展兼容其他浏览器
V2.0.7 => 剔除debug时留下的log信息
V2.0.6 => 优化全选的交互逻辑
          api优化：getReduceNode响应的node节点剔除掉渲染消息用不到的属性，使其更加精简
          BUG修复: 当删除非最后一个tag标签时指向异常
v2.0.0 => 大版本更新：推翻重构了所有的光标处理、文本和HTML写入、折行、退格删除、光标移动逻辑，不再采用0宽字符的处理方式（该方式下光标难以细致化控制）
          新增api：getReduceNode() => 获取精简后的dom
```
```
v1.6.3 => 交互优化：左右键盘切换光标时将跳过0宽字符，解决@人员标签需要连续敲击两下光标才能向左或向右移动光标
          BUG修复：修复@人员标签和图片在谷歌浏览器会存在ctrl+a全选后无法删除的问题
v1.6.2 => 代码小优化：元素的显示隐藏统一方法控制
          api小优化：getCallUserList响应的人员列表顺序将按照文本框内@标签的顺序，不再按照传入的userList数组顺序
v1.6.1 => 简易的demo页部署
          api优化：调用insertHtml光标不在文本框内时，将插入在最后一次在文本框的位置而不是在最后
          BUG修复：getCallUserList添加@所有人的特殊标识
v1.5.9 => bug修复：修复insertHtml会插入其他区域的光标处
v1.5.8 => api优化：修改insertText()插入方式
          api优化：更加的精简getHtml返回的内容
          BUG修复：修复谷歌浏览器在@标签后面没有元素时输入框无法聚焦
v1.5.6 => md添加图文说明
v1.5.5 => 开放文本框支持图片粘贴功能
          扩容新字段：copyType 控制输入框粘贴模式
v1.5.0 => 新增api：getText() => 获取输入纯文本内容
          新增api：getHtml() => 获取输入html内容
          部分方法名修改，使其更加的见名知意：
          setUserList(旧) => updateUserList(新) 
          isUnText(旧) => isEmpty(新)
          resizeText(旧) => clear(新)
v1.4.3 => 优化placeholder显隐逻辑
v1.4.1 => 重大更新：重写了退格删除关联元素逻辑 （旧版本@人员的相关插入元素可能需要退格删除两次才生效）
          火狐浏览器优化退格光标的定位
          轻量化@人员标签所绑定的数据，大幅度减轻html长度
          优化文本非空逻辑isUnText判断
v1.3.7 => 修复搜索匹配人员时下次打开查询框旧值未清空问题
v1.3.6 => 移除输入框的边框样式 方便使用者将元素作为嵌入自己业务使用开发
v1.3.5 => @人员列表扩容拼音查询字段：pinyin 可以自行下载pinyin-pro以支持该交互效果
          优化搜索展示图片的src来源，将第一次加载的头像资源缓存，避免重复请求获取
          修复搜索边距样式 
v1.3.2 => @人员列表扩容展示用户头像字段：avatar
v1.3.1 => 优化tag元素插入的代码逻辑
v1.3.0 => 新增人员筛选功能
          新增tab标签删除功能
v1.2.0 => 新增@人员多选功能
          人员搜索筛选功能即将推出
v1.1.1 => 人员筛选入口隐藏（尚未开发完毕）
v1.1.0 => 添加 placeholder 功能
          所有交互产生的样式变更由 style 提取抽离至 class
          添加新api isUnText 识别文本是否为空
v1.0.4 => 正式版发布
```

## LICENSE

MIT
