vue下自己开发富文本编辑器(二)带你从入门到放弃,个人已经基本开发完成

上一篇总结:

上一篇其实代码开发方面,基本原理都看的差不多了,但是发生了无限嵌套的问题。

总结下富文本遇到的问题:

1、元素跨标签处理

2、如何正确选择到你要的元素

3、跨行设置元素未选中部分换行(默认回车事件导致)

4、多个功能直接交叉使用问题(要有取舍)

5、css新旧混合问题

6、代码块插入问题

7、其实还有更多问题,但是没有开发过的那真的不知其中各种滋味…………

目前还未解决的问题:

实现csdn的回车标签(这个问题比较特殊,操作太多之后会样式滞留,还有就是回车无法顺利回车的问题都需要单独的回车操作)

这里希望csdn的开发组看到之后,能告诉下我csdn的富文本的回车操作怎么实现的。现在没有思绪

核心代码部分:

这个是我认为的最核心操作部分,这里最核心的就是文档片段的操作。

因为操作原理在于先得到你选中的元素,然后再操作这部分元素,再重新插入进去。(先选后得到元素处理,然后删除重新插入,先删后插

我的代码没做什么兼容性,从上一次开发到现在满打满算其实是一周的样子。

还有一个比较关键的代码是,基本上自定义的操作都是靠这个api来实现的。

document.execCommand("insertHTML", false, `<br>`);
import { CursorAcquisition } from "./selection";
import { delCss } from "./tool";
//文档片段处理
const domFragmentHandle = () => {
  const { range } = CursorAcquisition();

  //获取需要操作的元素进行处理
  let domst = range.commonAncestorContainer;
  domst = domst.nodeType === 1 ? domst : domst.parentNode;

  //获取元素中的css属性getSelectionText
  let cssText = domst.style.cssText;

  let innerhtml = "";
  console.log("当前获取的节点", domst.nodeName);
  //处理节点名称,若果为指定的元素则返回空
  let nodeName = domst.nodeName;
  let nodelist = ["div"];

  if (nodelist.indexOf(nodeName.toLocaleLowerCase()) !== -1) {
    nodeName = "";
  }
  nodeName = nodeName.toLocaleLowerCase();

  //判断处理,如果父节点是最大的div则更换选取方式
  if (domst.id === "dht-editor-content") {
    let span = document.createElement("span");
    let elem = range.cloneContents();
    span.appendChild(elem);
    innerhtml = span.innerHTML;
  } else {
    //console.log(domst.childNodes);
    //dom元素处理,不要多余标签,将字符串抽离,但是注意保持文档结构,
    // 但是该操作会导致多行的文档缩进等无效
    let child = domst.childNodes;
    for (let i = 0; i < child.length; i++) {
      if (child[i].nodeName === "BR") {
        innerhtml += `<br>`;
      } else {
        let node = child[i];
        innerhtml += node.nodeValue ? node.nodeValue : node.innerText;
      }
    }
  }

  //最终返回需要的元素
  return {
    innerhtml,
    cssText,
    nodeName
  };
};
//独立选中区域文字
const getSelectionText = () => {
  const { range } = CursorAcquisition();

  //获取元素中的css属性
  let cssText = "";

  let span = document.createElement("span");
  let elem = range.cloneContents();
  span.appendChild(elem);
  let innerhtml = span.innerHTML;

  //最终返回需要的元素
  return {
    innerhtml,
    cssText
  };
};
//最终执行函数
const execOperation = (name, value = null) => {
  const { range } = CursorAcquisition();
  if (!range.toString()) {
    console.log("未选中任何元素");
    return false;
  }
  let bool = document.execCommand(name, false, value);

  range.detach();

  return bool;
};
//生成html字符串
//传入参数:
/*
 * 插入的节点名称,
 * style:del: 需要删除的css名称
 * css:最后应用的css
 * */
const combinationHtml = style => {
  const { innerhtml, cssText, nodeName } = domFragmentHandle();
  let delcss = style.del || "";
  let css = style.css || "";
  let node = style.node || "span";
  let url = style.url;

  //let html = style.html || `<${node} style="${oldCss}; ${css}">${innerhtml}</${node}>`
  //之前的css
  let oldCss = cssText ? delCss(cssText, delcss) : "";

  console.log("html处理得到", nodeName);
  //新老节点判断处理,特殊的节点需要使用老节点比如span无法和h2混合
  if (nodeName && node !== nodeName && node !== "a") {
    node = nodeName;
  }
  //定义需要插入的html元素
  let html = "";
  if (node === "a") {
    html = `<${node} href="${url}" style="${oldCss}; ${css}">${innerhtml}</${node}>`;
  } else {
    html = `<${node} style="${oldCss}; ${css}">${innerhtml}</${node}>`;
  }

  console.log(html);
  return html;
};
export { domFragmentHandle, execOperation, getSelectionText, combinationHtml };

 个人git地址:

https://github.com/ht-sauce/dream

富文本文件地址:

dream/src/components/richTextEditor/

访问地址:http://localhost:8080/dht_blog/richTextEditor

中间开发到一半吧有点想放弃:

原因在于我加了wang富文本的群,里面一个开发说,你这样没意义,浪费时间,还大言不惭的说给我一年时间我也能写一个(关爱zhizhang),说实在我到现在为止完全没有什么帮助,还好有wang富文本开源。(感谢)

献上wang富文本地址:http://wangeditor.com

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章