H5编辑器核心思想的实例分析


本文摘自PHP中文网,作者零下一度,侵删。

代码和特性在chrome49下测试有效。

文本渲染的本质是对文本节点的渲染,通过浏览器内置的对象Range可以获得选择的起始点、与终止点

1

2

var range = getRangeObject();var start = range.startOffset,

end = range.endOffset;var startContainer = range.startContainer;var endContainer = range.endContainer;

getRangeObjec代码如下

1

2

3

4

5

6

7

8

function getRangeObject(){if(window.getSelection)

{var selection = window.getSelection();if(selection.rangeCount > 0)

{return selection.getRangeAt(0);

}

}else if(document.selection)

{return document.selection.createRange();

}return null;

};

 起始点始终在左面,终止点始终在右面,不受选择方向的影响。

  只有当起始点的开头或终止点的末尾是<br/>时,返回的不是文本节点,可以通过start,end确定br元素的位置分别是startContainer.childNodes[start],endContainer.childNodes[end-1]。返回的是文本节点start表示光标相对于起始文本节点所在的起始位置,end表示光标相对于终止文本节点所在的终止位置。

获得下一个文本节点的算法为

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

function getNextTextNode(startNode,dir = "nextSibling"){//记录startNode变化之前的状态,startNode变化后无效时便于状态的回滚let unchangeNode = startNode;if(startNode.nodeType == 3){

        startNode = startNode[dir];

    }while (true){if(startNode == undefined){if(unchangeNode == undefined){//保护机制throw new Error("程序会陷入死循环");break;

            }/*startNode所在的父元素所有选中节点遍历完毕,将sartNode指向父元素的兄弟节点*/let parent = unchangeNode.parentElement;

            unchangeNode = parent;

            startNode = parent[dir];

        }else if(startNode.nodeType == 3){//文本节点则退出循环break;

        }else if(startNode.tagName == "BR"){//处理单标签,避免不必要的迭代unchangeNode = startNode;

            startNode = startNode[dir];

        }else if(startNode.nodeType == 1){/*如果是双标签元素则进入*/unchangeNode = startNode;if(dir == "previousSibling"){

 

                startNode = $(startNode).contents().last().get(0);

            }else if(dir == "nextSibling"){

                startNode = $(startNode).contents().first().get(0);

            }else {//便于错误的定位throw new Error("错误的遍历方向:"+dir);

            }

        }else {//便于错误的定位throw new Error("不期待的元素类型=》"+startNode);

 

        }

    }    return startNode;

     

}

  //上述函数用外部变量+while循环的方式取代递归,加入的保护机制减少误用、潜在bug导致极差的体验。
获得起始节点和结束节点之间的所有文本节点

1

2

3

4

5

6

7

8

function getTextNodes(startTextNode,endTextNode){

    let textNodeArray = [];

    let node = startTextNode;while (true) {

        node = getNextTextNode(node);if(node == endTextNode){break;

        }

        textNodeArray.push(node);

    }    return textNodeArray;

}

以上就是H5编辑器核心思想的实例分析的详细内容,更多文章请关注木庄网络博客

相关阅读 >>

h5中怎样使用postmessage实现两个网页间传递数据

利用HTML5实现简单的拖动功能

【h5开发工具】2017最好用的10种HTML5应用开发工具推荐

HTML5制作屏幕手势解锁功能

video标签无法播放mp4问题在HTML5中的解决办法

HTML5 progress进度条详解

HTML5 canvas绘制时指定颜色与透明度的方法

head标签中有什么属性?

图片懒加载是什么意思?图片懒加载的实现方法

HTML5 filereader接口的详细介绍

更多相关阅读请进入《HTML5》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...