vue web-highlighter 划词高亮功能实现及遇到的问题(线上图书)

发布于:2024-12-18 ⋅ 阅读:(81) ⋅ 点赞:(0)

 gitcode web-highlighter 快速通道

gitHub web-highlighter 快速通道

1、下载插件

npm i web-highlighter

2、引入插件

import Highlighter from "web-highlighter";

3、初始化插件

mounted(){
    this.highlighter = new Highlighter({
        $root: document.getElementById("preview_text"), // 使用位置的根元素
        exceptSelectors: null, // 如果元素与选择器匹配,则不会突出显示
        wrapTag: "span",
        style: {
          className: ["double-line-highlight", "yellowline-color-highlight"],
        },
        verbose: false, // 它需要输出(打印)一些警告和错误消息吗
        exceptSelectors: [], // 要跳过的元素   'h1', '.title'
      });
}

4、使用

 <div id="preview_text" class="content" v-html="bookInfo" 
          @mouseup.navtive="mouseup_highlight">
        </div>
.exam_hig {
  background-color: red;
}
// 通过 window.getSelection() 获取用户选中元素
mouseup_highlight(event){
    var that = this;
    that.active_event = event.target; // 选中标签
    that.sel = window.getSelection(); // 选中文本
    that.range = that.sel.getRangeAt(0) // 获取范围对象
}


// 保存接口
postHig(){
    // 也可以在保存之前修改高亮器的选项。参数结构与构造函数相同,可以只传递部分选项。
    this.highlighter.setOption({
          style: {
            className: ['exam_hig'],
          },
        });
    // highlighter.fromRange(range) 创建高亮区域时由web-highlighter生成的一种特殊对象。为了在后台(数据库)中持久化表示DOM节点,需要找到一种数据结构,这就是web-highlighter中的HighlightSource。
    this.HighlightSource = await this.highlighter.fromRange(this.range);
    this.HighlightSource.claName = 'exam_hig'  // 这是因项目需要不同高亮效果我自己自定义的高亮类名
    var formdata = new FormData();
    formdata.append("highlightSource", JSON.stringify(this.HighlightSource));
    // 将高亮后的信息保存到数据库
    const { data, code, msg, count } = await this.$https.postHighlightSource()
}

HighlightSource 返回的属性的意义:

  • start:关于起始元素的元信息
  • end:关于结束元素的元信息
  • text:文本内容
  • id:唯一标识符

注意:修改、删除都需要用到 id

5、页面回显

// 获取高亮列表
getHigList(){
    let formData = new FormData();
    const { data, code, msg } = await this.$https.getHighlightSourceList(formData);
    if(code == 200){
        this.hig_list = data
        this.hig_list.forEach(item=>{
           var info_block = JSON.parse(item.higObj); // 返回的高亮信息
           var location_dom = this.highlighter.getDoms(info_block.id) // 获取位置
           if (location_dom.length == 0) {
              this.highlighter.setOption({
                style: {
                  className: info_block.claName,
                },
              });

              this.HighlightSource = await this.highlighter.fromStore(
                info_block.startMeta,
                info_block.endMeta,
                info_block.text,
                info_block.id
              );

        )
    }
}

 注意:返回的列表需要排序!!!不然可能导致高亮位置错误!!!

6、修改

// id 为  HighlightSource 对象中的高亮唯一标识
editHig(id){
    // 直接切换类名
    this.highlighter.removeClass('redClassName', id);
    this.highlighter.addClass('greenClassName', id);
}

7、删除

// id 为  HighlightSource 对象中的高亮唯一标识
delHig(id){
    this.highlighter.remove(id);
}

8、销毁

beforeDestroy(){
    // 当你不再需要使用高亮功能时,需要先使用该方法来移除一些事件监听,回收一些资源。
    this.highlighter.dispose();
}

遇到的问题:

1、回显高亮位置错误

        可能是列表没有排序导致的(反正我就是)因为这个插件是一个序列化与反序列化的过程

2、HighlightSource  返回为 null

        可能是没有正确获取到标签导致的,需要先完成页面的DOM加载后再获取。


网站公告

今日签到

点亮在社区的每一天
去签到