editorButtom.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. import E from 'wangeditor';
  2. const { BtnMenu } = E;
  3. // 菜单 class ,Button 菜单继承 BtnMenu class
  4. export default class MyMenu extends BtnMenu {
  5. constructor(editor) {
  6. const $elem = E.$(
  7. '<div class="w-e-menu" data-title="格式刷"> <i class="iconfont icon-geshishua"></i></div>'
  8. );
  9. super($elem, editor);
  10. const me = this;
  11. me.editor = editor;
  12. // 监听编辑器鼠标释放事件
  13. editor.$textElem.on('mouseup', () => {
  14. // 如果格式刷功能出于激活状态
  15. if (me._active) {
  16. // 延迟执行,避免获取不到正确的元素
  17. setTimeout(() => {
  18. // 复制格式刷样式
  19. pasteStyle(editor);
  20. // 取消格式刷激活样式
  21. // me.unActive();
  22. }, 10);
  23. }
  24. });
  25. editor.$textElem.on('click', () => {
  26. // 如果格式刷功能出于激活状态
  27. if (me._active) {
  28. // 延迟执行,避免获取不到正确的元素
  29. setTimeout(() => {
  30. // 复制格式刷样式
  31. pasteStyle(editor);
  32. // 取消格式刷激活样式
  33. // me.unActive();
  34. }, 10);
  35. }
  36. });
  37. }
  38. // 菜单点击事件
  39. clickHandler(e) {
  40. const editor = this.editor;
  41. if (this._active) {
  42. this.unActive();
  43. editor.copyStyleList = null;
  44. } else {
  45. // 激活按钮
  46. this.active();
  47. // 获取格式刷样式
  48. const containerEle = editor.selection.getSelectionContainerElem()?.elems[0];
  49. if (containerEle == null) return;
  50. const copyStyleList = parseDom(containerEle);
  51. // 保存格式刷样式
  52. editor.copyStyleList = copyStyleList;
  53. }
  54. }
  55. tryChangeActive() {}
  56. }
  57. // 复制选中dom的样式
  58. function parseDom(dom) {
  59. let targetDom = null;
  60. const nodeArray = [];
  61. getTargetDom(dom);
  62. getAllStyle(targetDom);
  63. function getTargetDom(dom) {
  64. const nbsp = dom.innerText.replace(/\s/g, '');
  65. let children = dom.children[0];
  66. if (nbsp == '') {
  67. children = dom.children[1];
  68. }
  69. for (const i of dom.childNodes) {
  70. if (i.nodeType === 3 && i.nodeValue && i.nodeValue.trim() !== '') {
  71. targetDom = dom;
  72. return;
  73. }
  74. }
  75. getTargetDom(children);
  76. }
  77. function getAllStyle(dom) {
  78. if (!dom) return;
  79. const tagName = dom.tagName.toLowerCase();
  80. if (tagName === 'p') {
  81. nodeArray.push({
  82. tagName: 'span',
  83. attributes: Array.from(dom.attributes).map((i) => {
  84. return {
  85. name: i.name,
  86. value: i.value
  87. };
  88. })
  89. });
  90. return;
  91. } else {
  92. nodeArray.push({
  93. tagName: tagName,
  94. attributes: Array.from(dom.attributes).map((i) => {
  95. return {
  96. name: i.name,
  97. value: i.value
  98. };
  99. })
  100. });
  101. }
  102. getAllStyle(dom.parentNode);
  103. }
  104. return nodeArray;
  105. }
  106. function addStyle(text, nodeArray) {
  107. let currentNode = null;
  108. nodeArray.forEach((ele, index) => {
  109. // 创建dom节点
  110. const node = document.createElement(ele.tagName);
  111. for (const attr of ele.attributes) {
  112. node.setAttribute(attr.name, attr.value);
  113. }
  114. if (index === 0) {
  115. node.innerText = text;
  116. currentNode = node;
  117. } else {
  118. node.appendChild(currentNode);
  119. currentNode = node;
  120. }
  121. });
  122. return currentNode;
  123. }
  124. // 粘贴
  125. function pasteStyle(editor) {
  126. const isEmptySelection = editor.selection.isSelectionEmpty();
  127. const $selectionElem = editor.selection.getSelectionContainerElem()?.elems[0];
  128. const isFont = $selectionElem?.nodeName.toLowerCase() !== 'p';
  129. const isSameValue = $selectionElem?.getAttribute('face') === editor;
  130. if (isEmptySelection) {
  131. if (isFont && !isSameValue) {
  132. const $elems = editor.selection.getSelectionRangeTopNodes();
  133. editor.selection.createRangeByElem($elems[0]);
  134. editor.selection.moveCursor($elems[0].elems[0]);
  135. }
  136. editor.selection.setRangeToElem($selectionElem);
  137. // 插入空白选区
  138. editor.selection.createEmptyRange();
  139. }
  140. // 获取格式刷保存的样式
  141. const copyStyleList = editor.copyStyleList;
  142. // 有样式说明格式刷被激活
  143. if (copyStyleList) {
  144. // 获取当前选中内容
  145. // 如果没选中也会执行,再次使用需要重新激活格式刷功能
  146. const text = editor.selection.getSelectionText();
  147. const targetDom = addStyle(text, copyStyleList);
  148. editor.cmd.do('insertHTML', targetDom.outerHTML);
  149. }
  150. }