Подтвердить что ты не робот

Установите позицию каретки сразу после вставленного элемента в contentEditable div

Я вставляю элемент в div contentEditable, но браузер устанавливает позицию курсора перед вставленным элементом. Можно ли установить курсор сразу после вставленного элемента, чтобы пользователь продолжал печатать, не переустанавливая позицию курсора?

4b9b3361

Ответ 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 = "";