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

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