recogito-js:用于文本注释/图像注释的前端插件

创建批注:

继续批注:

右侧批注列表:

1、功能与应用

  • 文本注释:recogito-js可以将注释功能添加到网页上,或者作为构建完全自定义注释应用程序的工具箱。
  • 图像注释:除了文本注释外,它还支持为网页中的图像添加绘图、注释和标签功能。
  • PDF注释:通过@recogito/recogito-react-pdf插件,它还能够支持在React中注释PDF文档。

2、官网及示例

官网:https://github.com/recogito/recogito-js/wiki/API-Reference

示例:https://recogito.github.io/recogito-js/

3、需求:

前面的文章提到过很多的tinyMCE、Vditor、cherryMarkdown、wangEditor等等markdown和富文本编辑器,在这些编辑器生成的文本内容的预览基础上要加上批注功能,用户选中文本后就要弹出批注弹窗,确认批注后右侧会相应展示出批注内容,同时在右侧进行批注的编辑、删除

4、安装与使用:

javascript 复制代码
npm i @recogito/recogito-js@1.8.2

以下示例为文本注释功能:

javascript 复制代码
import { Recogito } from "@recogito/recogito-js";
import "@recogito/recogito-js/dist/recogito.min.css";

// 初始化批注
const initRecogito = () => {
  getAnnoList();
  r = new Recogito({
    content: document.querySelector(".artDetail"), // 批注区域
    readOnly: false,  // 是否只读
    locale: "auto", // 可选择语言 auto会根据浏览器设置选择语言
  });
  r.setServerTime(Date.now()); // 设置批注日期
  r.setAuthInfo({   // 这里设置每个批注携带的默认信息
    id: useUserStore().userId,
    displayName: useUserStore().nickName,
  });
  // 创建批注事件
  r.on("createAnnotation", async function (annotation, overrideId) {
    // 定义一个getInitAnnotate方法拿到创建的这个批注信息
    let newAnno = getInitAnnotate("create", annotation);
    // 因为批注插件不管有没有输入内容都会创建,这里要求了没有批注内容时不允许新建批注
    if (!newAnno.annotationContent?.trim()?.length) {
      getAnnoList(); // 刷新批注列表避免页面出现空批注内容
      return proxy.$modal.msgWarning("请先输入批注内容");
    }
    // 将批注信息存入后端
    submitAnnotation(newAnno)
      .then(({ data }) => {
        recogitoList.value.push(data);  // 在页面右侧回展示批注信息
        proxy.$modal.msgSuccess("新增成功!");
      })
      .catch((err) => {
        getAnnoList();// 刷新批注列表避免页面出现空批注内容
      });
  });

 

  // 在已有批注基础上补充批注
  r.on("updateAnnotation", function (annotation, previous) {
    let newAnno = getInitAnnotate("update", annotation);
    if (!newAnno.annotationContent?.trim()?.length) {
      getAnnoList();
      return proxy.$modal.msgWarning("请先输入批注内容");
    }
    submitAnnotation(newAnno)
      .then(({ data }) => {
        // 补充批注时
        let index = recogitoList.value.findIndex((item) => item.id === data.id);
        recogitoList.value[index] = data;
        proxy.$modal.msgSuccess("新增成功!");
      })
      .catch((err) => {
        getAnnoList();
      });
  });
};

// 更改批注参数
const getInitAnnotate = (title, newAnno, pkId) => {
  let data = {};
  // 创建批注时
  if (title === "create") {
    data.annotationContent = newAnno.body[0]?.value;
    data.textContent = newAnno.target.selector.find(
      (item) => item.type === "TextQuoteSelector"
    )?.exact;
  // 修改批注时
  } else if (title === "update") {
    data.annotationContent = newAnno.body[newAnno.body?.length - 1]?.value;
  } else {
    // 通过外部input框编辑批注
    let annoBody = newAnno.body.find((item) => item.pkId === pkId);
    data.annotationContent = annoBody?.iptValue;
    data.pkId = pkId;
  }
  let annoPosition = newAnno.target.selector.find(
    (item) => item.type === "TextPositionSelector"
  );
  // 按照后端入参要求组装批注内容的结构
  data.annotationId = newAnno.id;
  data.createdBy = useUserStore().name;
  data.endCoordinate = annoPosition.end;
  data.startCoordinate = annoPosition.start;
  data.knwlgId = artDetails.value.pkId;
  data.knwlgNo = artDetails.value.knwlgNo;
  return data;
};

// 获取批注列表并回显
const getAnnoList = () => {
  getAnnotationList({ knwlgId: artDetails.value.pkId })
    .then((res) => {
      recogitoList.value = res.data;  // 批注列表
      setTimeout(() => {
        r.clearAnnotations(); //清除所有批注
        r.setAnnotations(recogitoList.value); // 设置已有批注内容
      }, 500);
    })
    .catch(() => {});
};

// 根据批注id在点击右侧批注列表激活文本域内批注弹窗
const selectAnnotation = (id) => {
  let domList = document.querySelectorAll(".r6o-annotation");
  let activeTop =
    Array.from(domList).find(
      (item) => item.dataset.id === id && item.innerText?.length
    )?.offsetTop - 5;
  document.querySelector(".article-container").scrollTop = activeTop;
  r.selectAnnotation(id);
};
相关推荐
cs_dn_Jie2 小时前
钉钉 H5 微应用 手机端调试
前端·javascript·vue.js·vue·钉钉
开心工作室_kaic3 小时前
ssm068海鲜自助餐厅系统+vue(论文+源码)_kaic
前端·javascript·vue.js
有梦想的刺儿3 小时前
webWorker基本用法
前端·javascript·vue.js
清灵xmf4 小时前
TypeScript 类型进阶指南
javascript·typescript·泛型·t·infer
小白学大数据4 小时前
JavaScript重定向对网络爬虫的影响及处理
开发语言·javascript·数据库·爬虫
qq_390161774 小时前
防抖函数--应用场景及示例
前端·javascript
334554325 小时前
element动态表头合并表格
开发语言·javascript·ecmascript
John.liu_Test5 小时前
js下载excel示例demo
前端·javascript·excel
PleaSure乐事5 小时前
【React.js】AntDesignPro左侧菜单栏栏目名称不显示的解决方案
前端·javascript·react.js·前端框架·webstorm·antdesignpro
哟哟耶耶5 小时前
js-将JavaScript对象或值转换为JSON字符串 JSON.stringify(this.SelectDataListCourse)
前端·javascript·json