2012-06-18 4 views
59

Я хотел бы создать простую функцию, которая добавляет текст в текстовую область в позиции курсора пользователя. Это должна быть чистая функция. Просто основы. Я могу выяснить остальное.Вставить текст в textarea в позицию курсора (Javascript)

+3

Возможный дубликат [Как вставить текст, где находится курсор?] (Http://stackoverflow.com/questions/7404366/how-do-i-insert-some-text-where-the-cursor- есть) –

+2

Посмотрите на этот ответ: http://stackoverflow.com/questions/4456545/how-to-insert-text-at-the-current-caret-position-in-a- textarea –

+1

Возможный дубликат [Вставка текста, в котором курсор использует Javascript/jquery] (http://stackoverflow.com/questions/1064089/inserting-a-text-where-cursor-is-using-javascript-jquery) – user

ответ

72
function insertAtCursor(myField, myValue) { 
    //IE support 
    if (document.selection) { 
     myField.focus(); 
     sel = document.selection.createRange(); 
     sel.text = myValue; 
    } 
    //MOZILLA and others 
    else if (myField.selectionStart || myField.selectionStart == '0') { 
     var startPos = myField.selectionStart; 
     var endPos = myField.selectionEnd; 
     myField.value = myField.value.substring(0, startPos) 
      + myValue 
      + myField.value.substring(endPos, myField.value.length); 
    } else { 
     myField.value += myValue; 
    } 
} 
+0

, что будет работать только в IE –

+1

Код Edited. Посмотрите сейчас – Rab

+0

почти работает в других: он теряет текущее положение. – user340140

40

Этот фрагмент кода может помочь вам с ней несколько строк JQuery 1.9+: http://jsfiddle.net/4MBUG/2/

$('input[type=button]').on('click', function() { 
    var cursorPos = $('#text').prop('selectionStart'); 
    var v = $('#text').val(); 
    var textBefore = v.substring(0, cursorPos); 
    var textAfter = v.substring(cursorPos, v.length); 

    $('#text').val(textBefore + $(this).val() + textAfter); 
}); 
+0

Отлично! Также работает с 1.6 с небольшими изменениями. –

+1

Но он не может заменить выделенный текст. –

+5

Для любого, кто хочет заменить выделенный текст: http://jsfiddle.net/4abr7jc5/2/ – mparkuk

0

Изменено его getElementById (MyField)

function insertAtCursor(myField, myValue) { 
    //IE support 
    if (document.selection) { 
     document.getElementById(myField).focus(); 
     sel = document.selection.createRange(); 
     sel.text = myValue; 
    } 
    //MOZILLA and others 
    else if (document.getElementById(myField).selectionStart || document.getElementById(myField).selectionStart == '0') { 
     var startPos = document.getElementById(myField).selectionStart; 
     var endPos = document.getElementById(myField).selectionEnd; 
     document.getElementById(myField).value = document.getElementById(myField).value.substring(0, startPos) 
      + myValue 
      + document.getElementById(myField).value.substring(endPos, document.getElementById(myField).value.length); 
    } else { 
     document.getElementById(myField).value += myValue; 
    } 
} 
+3

Это ударит по DOM-каналу больше, чем вам нужно. Сохранение 'myfield' как локального намного лучше для производительности – TMan

+0

Вау, действительно слишком много повторение 'document.getElementById (myField)'! Сделайте это один раз вверху и используйте имя переменной. Сколько раз подряд вы намерены избыточно искать один и тот же элемент? – doug65536

21

Ради надлежащего Javascript

HTMLTextAreaElement.prototype.insertAtCaret = function (text) { 
    text = text || ''; 
    if (document.selection) { 
    // IE 
    this.focus(); 
    var sel = document.selection.createRange(); 
    sel.text = text; 
    } else if (this.selectionStart || this.selectionStart === 0) { 
    // Others 
    var startPos = this.selectionStart; 
    var endPos = this.selectionEnd; 
    this.value = this.value.substring(0, startPos) + 
     text + 
     this.value.substring(endPos, this.value.length); 
    this.selectionStart = startPos + text.length; 
    this.selectionEnd = startPos + text.length; 
    } else { 
    this.value += text; 
    } 
}; 
+0

очень хорошее расширение! работает так, как ожидалось. Благодаря! –

+0

Лучшее решение! Спасибо –

6

Мне нравится простой javascript, и у меня обычно есть jQuery. Вот что я придумал, исходя от mparkuk's:

function typeInTextarea(el, newText) { 
    var start = el.prop("selectionStart") 
    var end = el.prop("selectionEnd") 
    var text = el.val() 
    var before = text.substring(0, start) 
    var after = text.substring(end, text.length) 
    el.val(before + newText + after) 
    el[0].selectionStart = el[0].selectionEnd = start + newText.length 
    el.focus() 
} 

$("button").on("click", function() { 
    typeInTextarea($("textarea"), "some text") 
    return false 
}) 

Вот демо: http://codepen.io/erikpukinskis/pen/EjaaMY?editors=101

7

Чистый JS модификация ответ Эрика:

function typeInTextarea(el, newText) { 
    var start = el.selectionStart 
    var end = el.selectionEnd 
    var text = el.value 
    var before = text.substring(0, start) 
    var after = text.substring(end, text.length) 
    el.value = (before + newText + after) 
    el.selectionStart = el.selectionEnd = start + newText.length 
    el.focus() 
} 

Испытано в Chrome только 47.

Если вы хотите, чтобы изменить значение выбранного текста в то время как вы печатаете в том же поле (для автозаполнения или аналогичного эффекта), проходят document.activeElement в качестве первого параметра.

Это не самый элегантный способ сделать это, но это довольно просто.

+0

, вы не закрыли линию с помощью >>; << – Phoenix

+0

Точки с запятой Phoenix являются необязательными в Javascript. Работает и без них. Хотя вы можете редактировать в точках с запятой, если хотите. Нет, biggie. –

+2

[Я сделал демонстрацию на JSFiddle.] (Https://jsfiddle.net/j77uezpL/) Он также работает с использованием «Версии 54.0.2813.0 канарейки (64-разрядной)», которая в основном является Chrome Canary 54.0.2813.0. Наконец, если вы хотите, чтобы он вставлялся в текстовое поле по идентификатору, используйте 'document.getElementById ('insertyourIDhere')' вместо 'el' в функции. – haykam

0

Публикация модифицировано функция для собственной справки. Этот пример вставляет выбранный элемент из <select> объекта и помещает курсор между тегами:

//Inserts a choicebox selected element into target by id 
function insertTag(choicebox,id) { 
    var ta=document.getElementById(id) 
    ta.focus() 
    var ss=ta.selectionStart 
    var se=ta.selectionEnd 
    ta.value=ta.value.substring(0,ss)+'<'+choicebox.value+'>'+'</'+choicebox.value+'>'+ta.value.substring(se,ta.value.length) 
    ta.setSelectionRange(ss+choicebox.value.length+2,ss+choicebox.value.length+2) 
} 
5

ответ Раба отлично работает, но не для Microsoft Edge, поэтому я добавил небольшую адаптацию к краю, а также:

https://jsfiddle.net/et9borp4/

function insertAtCursor(myField, myValue) { 
    //IE support 
    if (document.selection) { 
     myField.focus(); 
     sel = document.selection.createRange(); 
     sel.text = myValue; 
    } 
    // Microsoft Edge 
    else if(window.navigator.userAgent.indexOf("Edge") > -1) { 
     var startPos = myField.selectionStart; 
     var endPos = myField.selectionEnd; 

     myField.value = myField.value.substring(0, startPos)+ myValue 
      + myField.value.substring(endPos, myField.value.length); 

     var pos = startPos + myValue.length; 
     myField.focus(); 
     myField.setSelectionRange(pos, pos); 
    } 
    //MOZILLA and others 
    else if (myField.selectionStart || myField.selectionStart == '0') { 
     var startPos = myField.selectionStart; 
     var endPos = myField.selectionEnd; 
     myField.value = myField.value.substring(0, startPos) 
      + myValue 
      + myField.value.substring(endPos, myField.value.length); 
    } else { 
     myField.value += myValue; 
    } 
} 
0
/** 
* Usage "foo baz".insertInside(4, 0, "bar ") ==> "foo bar baz" 
*/ 
String.prototype.insertInside = function(start, delCount, newSubStr) { 
    return this.slice(0, start) + newSubStr + this.slice(start + Math.abs(delCount)); 
}; 


$('textarea').bind("keydown keypress", function (event) { 
    var val = $(this).val(); 
    var indexOf = $(this).prop('selectionStart'); 
    if(event.which === 13) { 
     val = val.insertInside(indexOf, 0, "<br>\n"); 
     $(this).val(val); 
     $(this).focus(); 
    } 
}) 
+0

Хотя это может ответить на вопрос, лучше объяснить основные части ответа и, возможно, в чем проблема с кодом OPs. – pirho

1

Если пользователь не касается ввода после того, как текст вставлен, «вход» событие никогда не срабатывает, а значение attribu т. е. не отражают изменения. Поэтому очень важно инициировать входное событие после программной вставки текста. Фокусировка поля недостаточно.

Ниже приводится копия Snorvarg's answer с триггером ввода в конце:

function insertAtCursor(myField, myValue) { 
    //IE support 
    if (document.selection) { 
     myField.focus(); 
     sel = document.selection.createRange(); 
     sel.text = myValue; 
    } 
    // Microsoft Edge 
    else if(window.navigator.userAgent.indexOf("Edge") > -1) { 
     var startPos = myField.selectionStart; 
     var endPos = myField.selectionEnd; 

     myField.value = myField.value.substring(0, startPos)+ myValue 
      + myField.value.substring(endPos, myField.value.length); 

     var pos = startPos + myValue.length; 
     myField.focus(); 
     myField.setSelectionRange(pos, pos); 
    } 
    //MOZILLA and others 
    else if (myField.selectionStart || myField.selectionStart == '0') { 
     var startPos = myField.selectionStart; 
     var endPos = myField.selectionEnd; 
     myField.value = myField.value.substring(0, startPos) 
      + myValue 
      + myField.value.substring(endPos, myField.value.length); 
    } else { 
     myField.value += myValue; 
    } 
    triggerEvent(myField,'input'); 
} 

function triggerEvent(el, type){ 
    if ('createEvent' in document) { 
    // modern browsers, IE9+ 
    var e = document.createEvent('HTMLEvents'); 
    e.initEvent(type, false, true); 
    el.dispatchEvent(e); 
    } else { 
    // IE 8 
    var e = document.createEventObject(); 
    e.eventType = type; 
    el.fireEvent('on'+e.eventType, e); 
    } 
} 

Кредит на plainjs.com для функции triggerEvent

Подробнее о oninput событии в w3schools.com

я обнаружил это при создании emoji-picker для чата.Если пользователь просто выбирает несколько эмоций и нажимает кнопку «отправить», поле ввода никогда не затрагивается пользователем. При проверке атрибута value он всегда был пустым, хотя в поле ввода были видны вставленные unicodes emoji. Оказывается, если пользователь не коснется поля, событие «вход» никогда не срабатывало, и решение должно было вызвать его таким образом. Понадобилось довольно много времени, чтобы понять это ... надеюсь, что это сэкономит время.