我正在将一个元素插入到contentEditable div中,但浏览器会在插入的元素之前设置光标的位置。是否可以在插入的元素后面设置光标,以便用户不必重新调整光标位置就可以输入?
答案 0 :(得分:29)
以下功能将执行此操作。 DOM Level 2 Range对象使这在大多数浏览器中变得容易。在IE中,您需要在插入的节点之后插入标记元素,将选择移动到它,然后将其删除。
实例:http://jsfiddle.net/timdown/4N4ZD/
代码:
function insertNodeAtCaret(node) {
if (typeof window.getSelection != "undefined") {
var sel = window.getSelection();
if (sel.rangeCount) {
var range = sel.getRangeAt(0);
range.collapse(false);
range.insertNode(node);
range = range.cloneRange();
range.selectNodeContents(node);
range.collapse(false);
sel.removeAllRanges();
sel.addRange(range);
}
} else if (typeof document.selection != "undefined" && document.selection.type != "Control") {
var html = (node.nodeType == 1) ? node.outerHTML : node.data;
var id = "marker_" + ("" + Math.random()).slice(2);
html += '<span id="' + id + '"></span>';
var textRange = document.selection.createRange();
textRange.collapse(false);
textRange.pasteHTML(html);
var markerSpan = document.getElementById(id);
textRange.moveToElementText(markerSpan);
textRange.select();
markerSpan.parentNode.removeChild(markerSpan);
}
}
或者,您可以使用我的Rangy library。那里的等价代码是
function insertNodeAtCaret(node) {
var sel = rangy.getSelection();
if (sel.rangeCount) {
var range = sel.getRangeAt(0);
range.collapse(false);
range.insertNode(node);
range.collapseAfter(node);
sel.setSingleRange(range);
}
}
答案 1 :(得分:1)
如果您要插入一个空div,p或span,我相信需要有一些东西&#34;在新创建的元素内部,以便抓住 - 以及将插入符号放在那里。
这是我的黑客,似乎在Chrome中运行正常。这个想法只是在元素中放入一个临时字符串,然后在插入符号后将其删除。
// Get the selection and range
var idoc = document; // (In my case it's an iframe document)
var sel = idoc.getSelection();
var range = sel.getRangeAt(0);
// Create a node to insert
var p = idoc.createElement("p"); // Could be a div, span or whatever
// Add "something" to the node.
var temp = idoc.createTextNode("anything");
p.appendChild(temp);
// -- or --
//p.innerHTML = "anything";
// Do the magic (what rangy showed above)
range.collapse(false);
range.insertNode( p );
range = range.cloneRange();
range.selectNodeContents(p);
range.collapse(false);
sel.removeAllRanges();
sel.addRange(range);
// Clear the non
p.removeChild(p.firstChild);
// -- or --
//p.innerHTML = "";
答案 2 :(得分:1)
这是在VueJS上下文中使用Rangy对我有用的东西。
// When the user clicks the button to open the popup to enter
// the URL, run this function to save the location of the user's
// selection and the selected text.
newSaveSel: function() {
if (this.savedSel) {
rangy.removeMarkers(this.savedSel);
}
// Save the location of the selected text
this.savedSel = rangy.saveSelection();
// Save the selected text
this.savedSelText = rangy.getSelection().toString();
this.showLinkPopup = true;
console.log('newSavedSel', this.savedSel);
},
surroundRange: function() {
// Restore the user's selected text. This is necessary since
// the selection is lost when the user stars entering text.
if (this.savedSel) {
rangy.restoreSelection(this.savedSel, true);
this.savedSel = null;
}
// Surround the selected text with the anchor element
var sel = rangy.getSelection();
var range = sel.rangeCount ? sel.getRangeAt(0) : null;
if (range) {
// Create the new anchor element
var el = document.createElement("a");
el.style.backgroundColor = "pink";
el.href = this.anchorHref;
el.innerHTML = this.savedSelText;
if (this.checked) {
el.target = "_blank";
}
// Delete the originally selected text
range.deleteContents();
// Insert the anchor tag
range.insertNode(el);
// Ensure that the caret appears at the end
sel.removeAllRanges();
range = range.cloneRange();
range.selectNode(el);
range.collapse(false);
sel.addRange(range);
this.showLinkPopup = false;
}
},