2010-05-27 6 views
36

У меня есть contenteditable DIV, где нужно вставить текст в позиции курсора,Вставить текст под курсором в контенте редактируемых ДИВ

Это можно легко сделать в IE с помощью document.selection.createRange().text = "banana"

Есть ли подобный способ внедрения этого в Firefox/Chrome?

(я знаю, решение существует here, но он не может быть использован в contenteditable DIV, и выглядит неуклюжим)

Спасибо!

+0

Если вы хотите вставить HTML на курсоре, см http://stackoverflow.com/questions/6690752/insert-html -at-caret-in-a-contenteditable-div – Kes115

ответ

110

Следующая функция вставляет текст в положение каретки и удаляет существующий выбор. Она работает во всех основных настольных браузерах:

function insertTextAtCursor(text) { 
    var sel, range, html; 
    if (window.getSelection) { 
     sel = window.getSelection(); 
     if (sel.getRangeAt && sel.rangeCount) { 
      range = sel.getRangeAt(0); 
      range.deleteContents(); 
      range.insertNode(document.createTextNode(text)); 
     } 
    } else if (document.selection && document.selection.createRange) { 
     document.selection.createRange().text = text; 
    } 
} 

UPDATE

На основе комментариев, вот некоторый код для сохранения и восстановления выбора. Перед отображением вашего контекстного меню вы должны сохранить возвращаемое значение saveSelection в переменной, а затем передать эту переменную в restoreSelection, чтобы восстановить выбор после скрытия контекстного меню и перед вставкой текста.

function saveSelection() { 
    if (window.getSelection) { 
     sel = window.getSelection(); 
     if (sel.getRangeAt && sel.rangeCount) { 
      return sel.getRangeAt(0); 
     } 
    } else if (document.selection && document.selection.createRange) { 
     return document.selection.createRange(); 
    } 
    return null; 
} 

function restoreSelection(range) { 
    if (range) { 
     if (window.getSelection) { 
      sel = window.getSelection(); 
      sel.removeAllRanges(); 
      sel.addRange(range); 
     } else if (document.selection && range.select) { 
      range.select(); 
     } 
    } 
} 
+0

Спасибо за помощь, я использую это как часть редактора онлайн-кода, в котором всякий раз, когда пользователь вводит "." после имени объекта появляется контекстное меню со списком его методов (intellisense/code completion). Когда пользователь нажимает имя метода, текст нужно вставить после точки в области кода div. Но до сих пор «имя метода» вставляется внутри контекстного меню не внутри области кода. – user314362

+1

ОК. В этом случае я бы предложил сохранить копию Range/TextRange, представляющую выделение, в тот момент, когда вы собираетесь отобразить контекстное меню, а затем восстановить выделение из него после скрытия контекстного меню, но перед вставкой текста. –

+0

См. Мой обновленный ответ. –

-2

только простой метод с JQuery:

Скопируйте все содержимое DIV

var oldhtml=$('#elementID').html();

var tobejoined='<span>hii</span>';

//element with new html would be

$('#elementID').html(oldhtml+tobejoined);

простой!

+1

Не разрешает начальный вопрос, он добавляет текст после содержимого html. – Tobi

0
  1. Получить объект с window.getSelection().
  2. Используйте Selection.getRangeAt(0).insertNode(), чтобы добавить текстовое поле.
  3. При необходимости переместите позицию курсора за добавленный текст с помощью Selection.modify(). (Не нормируется, но эта функция поддерживается в Firefox, Chrome и Safari)

    function insertTextAtCursor(text) 
    { 
        let selection = window.getSelection(); 
        let range = selection.getRangeAt(0); 
        range.deleteContents(); 
        let node = document.createTextNode(text); 
        range.insertNode(node); 
    
        for(let position = 0; position != text.length; position++) 
        { 
         selection.modify("move", "right", "character"); 
        }; 
    }