• 初试富文本编辑器


    都说富文本编辑器是天坑,我也去坑边看一眼

    为什么都说富文本编辑器是天坑?。早就听说过富文本编辑器,一般看到这种标题都会让人有一种想去试试的冲动,至少也要去溜达一圈,就像地牢围攻1的绝望洞一样。于是我去MDN上找了找教程。原来现成的代码都有。

    要尝试点什么?

    1. MDN的代码,无法实现光标位置变化之后,读取光标处的文本格式,并改变样式按钮状态的功能。比如word里面,光标处的文本是加粗的话,工具栏的加粗按钮就变成按下状态,离开这段区域之后又会变成未按下状态。要实现这个功能,基本思路就是利用点击和键盘事件加上queryCommandState,大致代码如下:

      var editor = document.getElementById('editor');
      editor.addEventListener('keyup', function() {
      statusCheck(buttons);
      });
      editor.addEventListener('mouseup', function() {
      statusCheck(buttons);
      });

      function statusCheck(buttons) {
      commands.forEach(function(command) {
      var state = document.queryCommandState(command.cmd);
      var className = buttons[command.cmd].className;
      if (state) {
      buttons[command.cmd].className = addClass(className, 'on');
      } else {
      buttons[command.cmd].className = removeClass(className, 'on');
      }
      });
      }

    2. 无法取得选中区域的文字。因为getSelection只返回选择的起始和结束的DOM元素及信息,如果想要取得所选文件,必须自己去遍历选中的DOM节点,取出其中的text节点。大致代码实现如下:

      function getSelectedText() {
      var selection = getSelection();

        // 取得开始的文字
        var anchorNode = selection.anchorNode;
        var anchorOffset = selection.anchorOffset;
        var focusNode = selection.focusNode;
        var focusOffset = selection.focusOffset;
      
        // 判断选择的方向
        var isForward = isNodeBefore(anchorNode, focusNode);
        var startNode;
        var endNode;
        var startOffset;
        var endOffset;
        if (isForward) {
            startNode = anchorNode;
            endNode = focusNode;
            startOffset = anchorOffset;
            endOffset = focusOffset;
        } else {
            startNode = focusNode;
            endNode = anchorNode;
            startOffset = focusOffset;
            endOffset = anchorOffset;
        }
      
        var text1 = '';
        if (startNode !== null) {
            var startText = startNode.data;
            text1 = startText.substring(startOffset);
        }
      
        // 取得结束的文字
      
        var text2 = '';
        if (endNode !== null) {
            var endText = endNode.data;
            text2 = endText.substring(0, endOffset);
        }
      
      
      
        //取得中间的文字
        var middleText = '';
        if (startNode !== null && endNode !== null) {
            middleText = getMiddleText(startNode, endNode);
        }
      
        return text1 + middleText + text2;
      

      }

      function getMiddleText(startNode, endNode) {
      if (startNode === null && endNode === null) {
      return;
      }

        var pivot = startNode;
        var middleText = '';
        var text;
        while(pivot !== endNode) {
            text = '';
            if (pivot.nextSibling === null) {
                if (pivot.parentNode === null) {
                    break;
                } else {
                    pivot = pivot.parentNode;
                }
            } else {
                pivot = pivot.nextSibling;
                text = traversal(pivot);
            }
            middleText += text;
        }
      
        return middleText;
      
        // 遍历节点选择文字
        function traversal(root) {
            if (pivot === endNode) {
                return '';
            }
            if (root.nodeType === 3) {
                return root.nodeValue;
            } else {
                var text = '';
                var childNodes = root.childNodes;
                for (var i = 0; i < childNodes.length; i++) {
                    if (childNodes[i] === endNode) {
                        pivot = endNode;
                        break;
                    }
                    text += traversal(childNodes[i]);
                }
                return text;
            }
        }
      

      }

      function isNodeBefore(startNode, endNode) {
      var startParents = getParents(startNode), endParents = getParents(endNode);
      var count = Math.min(startParents.length, endParents.length);
      var commonParent, startParent, endParent;
      for (var i = 0; i < count; i++) {
      startParent = startParents[startParents.length - i - 1];
      endParent = endParents[endParents.length - i - 1];
      if (startParent === endParent) {
      commonParent = startParent;
      } else {
      var startPos = convertToArray(commonParent.childNodes).indexOf(startParent);
      var endPos = convertToArray(commonParent.childNodes).indexOf(endParent);
      return startPos < endPos;
      }
      }
      return true;
      }

    难得能用上一点点数据结构的知识

    完整代码

    尽管惨不忍睹,我还是献丑放上来。不被婊怎么进步,虽然我觉得也不会有人觉得值得花功夫婊。(以后再也不贴大段代码了,调格式好累。这次就当充数了。结果调格式的过程中自己给自己增加了点击量)

  • 相关阅读:
    一:多线程--多线程简单介绍
    五:网络--多线程断点下载
    四:网络--NSURLConnection基本使用
    三:网络--数据安全/加密
    二:网络--GET请求和POST请求
    一:网络--HTTP协议
    源代码管理工具GIT
    MyBatis 多参问题
    jquery 事件
    jquery点击事件
  • 原文地址:https://www.cnblogs.com/linden5/p/7580642.html
Copyright © 2020-2023  润新知