https://hackernoon.com/easily-create-an-html-editor-with-designmode-and-contenteditable-7ed1c465d39b

https://www-archive.mozilla.org/editor/midasdemo/

  1. chrome的debug方式是从inspact element入手的. 可以一路跟踪过去.
  2. 基本上操作都是依赖于document的. 这个editable的document貌似都能搞.
  3. 用MutationObserver监视document的修改.
事件
  • DocumentOrShadowRoot.elementFromPoint()返回指定坐标处的最顶层元素。 实际上这个并不生效, 很神奇.
  1. DocumentOrShadowRoot.elementsFromPoint() 返回指定坐标处的所有元素的数组, 这个也不生效

  2. Document.createRange() 新建一个

  3. Document.createTextNode() 新建一个文本节点(不含标签的节点).

  4. DocumentOrShadowRoot.activeElement Read only

    返回得到焦点的element, 这个生效, 但是没啥用.

  5. GlobalEventHandlers.onchange 被改变.

  6. Document.createElement()

    使用给定的标记名称创建新元素

貌似上面的都没用

真正有用的的是

  • document.getselection
  • Document.caretRangeFromPoint() 从光标位置拿到range.
  • MutationObserver, 这个事件监控dom树的修改.
  • execcommand应该有用, 看看是否有针对整行进行正则的做法. Todo.

######

document
document.execCommand('insertHTML', false, '&#009') //在当前光标插入内容.
document.createTextNode('哈哈哈哈'); //建一个纯文字节点(不含标签)
document.caretRangeFromPoint(e.clientX, e.clientY); //拿到点, 可以插入内容的点.
document.elementFromPoint(560,238) //这个结果是正确的.
拿到一个range
let range = document.caretRangeFromPoint(e.clientX, e.clientY);
range.insertNode(cur) // 这样就可以了, 之前是#cur的样式设置的不好.
range.insertNode(document.createTextNode("dadadadadada"));
let offset = range.startOffset;

element
继承链

eventtarget <- node <- element <- htmlelement <- HTMLinputelement / HTMLimageelement……

核心属性
  • offsetWidth, 一个包含border和padding的宽度, 不含margin.
  • getBoundingClientRect()方法返回元素的大小及其相对于viewport的位置。
    • 返回的是一个domrect(TextRectangle或 ClientRect 的别称),
    • 包含top right bottom left
selection 是关键: https://developer.mozilla.org/en-US/docs/Web/API/Selection
var selection = documentOrShadowRootInstance.getSelection()  // 这样也就拿到了一个selection
 Window.getSelection()  //更多的时候, 我们应该调用这个函数.
anchornode //选择起点
anchoroffset //起点偏移量
focusnode //终点
focusoffset
iscollapsed //判断起点和终点是否重合. 也就是只有光标没有选择.
containnode //判断node是否是当前选区的一部分.
window

代表dom运行的窗口, 一个tab就是一个窗口. 不适合放到document上面的属性都放在窗口上.

  • scroll 类的内容都在这个接口.
  • size类也在这里.
  • open和move也在这里.
  • 对我们而言selection是最重要的了.
从顶层看

document和window是根本的interface.