光标处理
光标处理, 需要一个总结
contenteditable的设置光标方式:
//得到selection
var sel = window.getSelection(); //这个是live的
var range = sel.getRangeAt(0); // 这个不是live. 如果没有caret, 那么这个就拿不到
//得到光标
window.getSelection().anchorOffset;
//设置光标
window.getSelection().collapse(editor, 0);
//得到range
range = window.getSelection().getRangeAt(0); //0代表第一个拖蓝
expandedSelRange = range.cloneRange(); //range可能要改变, 比如插入node.
//设置range
expandedSelRange.setEndAfter(lastNode);//有答案加了这一句, 因为插入range的内容是最后的node.
sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
光标处插入
function insertHtmlAtCursor(html) {
var range=window.getSelection().getRangeAt(0);
var node = range.createContextualFragment(html);//这个有问题.
var newNode = document.createTextNode('不用fregment???'); //这个就OK了.
range.deleteContents();// 某些答案用了这个. 删除了range现有内容.
range.insertNode(node);
}
var tagString = "<div>I am a div node</div>";
var range = document.createRange();
range.selectNode(editor); //指定插入位置editor
var documentFragment = range.createContextualFragment(tagString);
document.body.appendChild(documentFragment);
包裹选蓝内容
var range = document.getSelection().getRangeAt(0);
var nnode = document.createElement("b");
range.surroundContents(nnode);
nnode.innerHTML = "Some bold text";
得到光标所在位置和内容
var sel = document.getSelection(),
nd = sel.anchorNode, //这里拿到node
text = nd.textContent.slice(0, sel.focusOffset);
var line=text.split("\n").length;
var col=text.split("\n").pop().length;
alert("row:"+line+", col:"+col )
得到光标做在的node, 没有看到直接得到element的方法
var sel = window.getSelection();
var range = sel.getRangeAt(0);
//selection方法 拿到node, 然后拿到nodeValue
sel.focusNode.nodeValue
sel.anchorNode.nodeValue
//range方法 拿到node, 然后拿到nodeValue
range.commonAncestorContainer.nodeValue
range.startContainer.nodeValue
range.endContainer.nodeValue
//selection方法 拿到具体光标在node中的位置:
sel.focusOffset
sel.anchorOffset
//range方法 拿到具体光标在node中的位置:
range.startOffset
range.endOffset
背景:
range 拖蓝
创建
Document
var range = document.caretRangeFromPoint(float x, float y);Selection
range = sel.getRangeAt(index)- 构造函数 range = new Range()
Document
range = document.createRange();
关键属性
- range.commonAncestorContainer 返回包含startContainer
and
endContainer的最小的node. - range.startContainer 返回包含range起点的node.
- range.endContainer 返回包含range终点的node.
- range.startOffset 在startcontianer中的range起点的位置
- range.endOffset 在endcontianer中的range终点的位置
- range.collapse 起点和终点是否重合
关键方法
- range.setStart(startNode, startOffset);
- range.setEnd(endNode, endOffset);
- range.selectNode(referenceNode); range包含整个referenceNode, range的父元素是referenceNode的父元素
- range.selectNodeContents(referenceNode); range包含referenceNode的内容, range的父元素是referenceNode
- range.collapse(toStart); 参数是bool, true收缩到起点, false收缩到终点, 默认false.
- range.insertNode(newNode);在
Range 的
起点处插入节点。 - clone = range.cloneRange(); clone一个range.
- documentFragment = range.createContextualFragment(tagString) 纯文本没有问题.
- Range.deleteContents()从dom删除range内容.
- documentFragment = range.extractContents(); 把range的内容从dom移动到一个fragment
- range.surroundContents(newParent); 把range内容包裹在newparent里面, 等于这两行语句:
newNode.appendChild(range.extractContents()); range.insertNode(newNode)
. - range.detach(); 通知运行环境, 可以释放range.
- bool = range.intersectsNode( referenceNode ) referenceNode是否在range里面.
selection 选区
拿到选区:
- selection = window.getSelection();
textarea的选区方式(contenteditable失效):
contenteditable.focus() //失效, 加了tabindex都不行 devtools失效, 用按钮的点击事件就是有效地.
contenteditable.selectionStart = 100 //这个确实无效, 因为他是HTMLInputElement的属性(而且必须是textinput).
contenteditable.selectionEnd = 200
textarea.focus() //成功
textarea.selectionStart = 100
textarea.selectionEnd = 200
//focus之后, 如果是devtools 都不会引起outline(蓝框), 如果是button点击事件触发, 那么篮筐outline正常
api命名规则
- anchor: 起点, 锚点
- focus: 终点, 焦点
属性
focusNode
返回该选区终点所在的节点。focusOffset
返回一个数字,其表示的是选区终点在focusNode
中的位置偏移量。- 如果 focusNode 是文字节点,那么选区末尾未被选中的第一个字,在该文字节点中是第几个字(从0开始计),就返回它。
- 如果 focusNode 是一个元素,那么返回的就是在选区末尾之后第一个节点之前的同级节点总数。
rangeCount
返回该选区所包含的range(拖蓝)的数量。
关键函数
- toString() 拿到纯文本.
- sel.collapse(parentNode, offset);将当前的选区折叠为一个点。
- sel.extend(node, offset)选区焦点扩展到指定位置, 锚点不变.
- sel.modify(alter, direction, granularity) 改变选区
- sel.containsNode(aNode,aPartlyContained) 判断节点aNode是否被(部分/全部)选中.
- range处理
- range = sel.getRangeAt(index) 返回指定的拖蓝range
- sel.addRange(range) 添加一个range
- sel.removeAllRanges()移除所有range, 取消所有选择.
- sel.removeRange(range)
node
属性
-
node.textContent, 一个节点及其后代的文本内容(含不可视的), 可以用来赋值
let text = aNode.textContent; //这个可以拿到所有文本, 完美哦. bNode.textContent = string; //此处有副作用, bNode里面的html标签会被抹掉.
-
previousNode = node.previousSibling
-
parentElement = node.parentElement
-
parentNode = node.parentNode, 父节点可能是element, 也可能是document, 也可能是documentfragment, 但是 document和documentfragment永远没有父节点.
-
let value = node.nodeValue; 对于text有用, 对于element没用.
-
var type = node.nodeType;
-
nextNode = node.nextSibling
-
var childNode = node.firstChild;
-
var ndList = elementNodeReference.childNodes; 这个live, 只读, nodelist类型
方法
-
Node.normalize()
对该元素下的所有文本子节点进行整理,合并相邻的文本节点并清除空文本节点。 -
element.appendChild(aChild), 实际上能加儿子的都是element. textnode不能有儿子.
-
let newClone = node.cloneNode([deep])
-
var insertedNode = parentNode.insertBefore(newNode, referenceNode);
-
let oldChild = node.removeChild(child);//OR element.removeChild(child);
-
parentNode.replaceChild(newChild, oldChild);
-
node.contains( otherNode ) //判断
-
var root = node.getRootNode(options);
- compareMask = node.compareDocumentPosition( otherNode )
nodelist
-
是live的.
-
Node.childNodes
这个属性就是 -
document.querySelectorAll()
这个的返回值也是
text
- 继承链: EventTarget < Node < CharacterData < Text
- 比如某个div的childNodes就包含了它内部的文字.
- newNode = textNode.splitText(offset), 这个函数就是拆分textnode
- document.createTextNode( “some text” )
- innerhtml也可以添加text
ParentNode
这个接口描述了所有有子元素的node, 他在element, document, documentfragment上面实现.
属性
- var count = node.childElementCount;
- let children = node.children; live的htmlcollection of elements
- var element = node.firstElementChild;
- const element = node.lastElementChild
方法
- ParentNode.append(…nodesOrDOMStrings) //插到最后一个子node之后, 可以是元素.
- ParentNode.prepend(…nodesToPrepend); //插到第一个子node之前, 可以是元素.
- element = parentNode.querySelector(selectors);
- elementList = parentNode.querySelectorAll(selectors);
element
-
innerHTML
const content = element.innerHTML; element.innerHTML = htmlString; //没有副作用
-
var cName = elementNodeReference.className; //空格分隔的class字符串 elementNodeReference.className = cName;
-
const DOMTokenList = elementNodeReference.classList;
- element.setAttribute(name, value);
htmlelement
-
innerText 得到可见文本内容
var renderedText = HTMLElement.innerText; HTMLElement.innerText = string; //有副作用, 会删除element包含的所有html标签
-
element.focus(options) 设置焦点到某个元素
-
HTMLElement.style.cssText = “color: blue; border: 1px solid black”;
HTMLInputElement
-
HTMLInputElement.selectionStart 只对input的text类元素生效
-
var labelElements = input.labels; 返回input的label, 比如checkbox和radiobox
-
HTMLInputElement.multiple
是否有多值, 目前就是file有这个属性 -
事件invalid event, 页面可以直接校验
-
element.setSelectionRange(selectionStart, selectionEnd [, selectionDirection]);
-
element.select(); 选择元素的所有内容
-
//替换range的所有内容 element.setRangeText(replacement); element.setRangeText(replacement, start, end [, selectMode]);
-
element.stepDown( [ stepDecrement ] ); 步进/步退
- element.stepUp( [ stepIncrement ] ); 步进/步退
document 和 window
window是个很特殊的对象, 他是document的window.
- focused = document.hasFocus(); 判断是否得到焦点.
- var element = DocumentOrShadowRoot.activeElement 拿到当前焦点元素.
- 实际用这个: document.activeElement
- var selection = documentOrShadowRootInstance.getSelection()
- 实际用这个: selection = window.getSelection(); 得到selection, 这个是live的.
- var caretPosition = document.caretPositionFromPoint(float x, float y);
- var element = document.elementFromPoint(x, y);
- var elements = document.elementsFromPoint(x, y);
- var style = window.getComputedStyle(element [, pseudoElt]);
- attribute = document.createAttribute(name)// = element.setAttribute(name, value);
- let fragment = document.createDocumentFragment();
- var element = document.createElement(tagName[, options]);
- var event = document.createEvent(type); 请使用CustomEvent来替代.
- var nodeIterator = document.createNodeIterator(root, whatToShow, filter);
- var text = document.createTextNode(“string”);
- document.createTreeWalker(root, whatToShow[, filter[, entityReferenceExpansion]]);
被废弃的方法
- document.queryCommandState(“bold”);
- Document.execCommand()