Я вставляю элемент в div contentEditable, но браузер устанавливает позицию курсора перед вставленным элементом. Можно ли установить курсор сразу после вставленного элемента, чтобы пользователь продолжал печатать, не переустанавливая позицию курсора?
Установите позицию каретки сразу после вставленного элемента в contentEditable div
Ответ 1
Эта функция выполнит следующую функцию. Объекты DOM Level 2 Range облегчают работу в большинстве браузеров. В IE вам нужно вставить элемент маркера после node, который вы вставляете, переместите выделение на него и затем удалите его.
Пример в реальном времени: 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. Эквивалентный код там был бы
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);
}
}
Ответ 2
Если вы вставляете пустой div, p или span, я считаю, что внутри вновь созданного элемента должен быть "что-то", чтобы диапазон мог захватить - и чтобы поместить туда каретку.
Вот мой хак, который, похоже, работает в Chrome. Идея состоит в том, чтобы просто вставить временную строку внутри элемента, а затем удалить ее, когда там находится карет.
// Get the selection and range
var idoc = document; // (In my case it 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 = "";