Итак, вы хотите сохранить выделение, когда вы фокусируете текстовую область и фокусируете на теге ввода.
Вам нужно запомнить выделение (начальную и конечную точки, когда текстовая область теряет фокус) и принудительно выделить выделение, чтобы оно сохранялось.
Чтобы запомнить выборку, вы можете сохранить el.selectionStart
и el.selectionEnd
в двух глобальных переменных внутри функции, которая вызывается при onblur()
событии тега textarea.
Тогда внутри вашего pasteIntoInput()
вы можете рассмотреть эти две точки для замены.
Для принудительного выбора - проверьте это решение для сохранения выбора. Однако здесь используется jquery, а не простой javascript.
Однако я не уверен, действительно ли решение работает. Я попробовал это здесь http://jsfiddle.net/sandeepan_nits/qpZdJ/1/, но это не работает, как ожидалось.
Обновление
Сомневаюсь, можно ли сохранить выбор после того, как фокус исчезнет Вероятно, для выбора необходим фокус, и ссылка на ответ, которую я дал, пытается сфокусироваться, а затем выбрать. В этом случае это не решит вашу проблему. Таким образом, альтернативы могут быть -
подделка текстовой области с помощью html div. Вы можете определить некоторые стили, чтобы создать эффект выделения и применить его onblur()
или использовать простой готовый редактор, если он доступен.
Отображение выделения динамически в отдельной области. Проверьте это демо jquery fieldSelection plugin . Помните, что вы уже сохраняете выделение в глобальных переменных для фактической замены. Вам нужно только отобразить пользователю выбор, который будет заменен. Я думаю, что отображение выбора отдельно, как эта демонстрация, экономит ваше время, и это тоже выглядит круто.
Но, конечно, зависит от ваших требований.
Дальнейшее обновление
Проверьте http://jsfiddle.net/sandeepan_nits/qpZdJ/2/ для работающей «Замена текста внутри текстовой области без фокуса» (как вы хотите), но без выделения на размытие. Я до сих пор не знаю, можно ли оставить выделение размытым.
Другое обновление (21 декабря)
Рабочее решение для IE, а также других браузеров
http://jsfiddle.net/sandeepan_nits/qpZdJ/24/
Вот тот же код: -
HTML -
<textarea id='text' cols="40" rows="20" onbeforedeactivate="storeSelectionIeCase();" onblur="storeSelectionOthersCase();">
</textarea>
<div id="opt">
<input id="input" type="text" size="35">
<input type="button" onclick='pasteIntoInput(document.getElementById("input").value)' value="button"/>
</div>
и все JS
var storedSelectionStart = null;
var storedSelectionEnd = null;
function pasteIntoInput(text)
{
el=document.getElementById("text");
el.focus();
if((storedSelectionStart != null) && (storedSelectionEnd != null))
{
start = storedSelectionStart;
end = storedSelectionEnd;
}
else
{
start = el.selectionStart;
end = el.selectionEnd;
}
if (typeof start == "number"&& typeof end == "number")
{
var val = el.value;
var selStart = start;
var end = selStart + text.length;
el.value = val.slice(0, selStart) + text + val.slice(end );
}
else if (typeof document.selection != "undefined")
{
var textRange = document.selection.createRange();
textRange.text = text;
textRange.collapse(false);
textRange.select();
}
}
function storeSelectionOthersCase()
{
if(!(isBrowserIE6() || isBrowserIE7()))
{
storeSelection();
}
else
{
return false;
}
}
function storeSelectionIeCase()
{
if((isBrowserIE6() || isBrowserIE7()))
{
storeSelection();
}
else
{
return false;
}
}
function storeSelection()
{
//get selection
el=document.getElementById("text");
var el = document.getElementById("text");
var sel = getInputSelection(el);
//alert("check"+sel.start + ", " + sel.end);
storedSelectionStart = sel.start;
storedSelectionEnd = sel.end;
//alert("see"+storedSelectionStart +" - "+storedSelectionEnd );
}
function getInputSelection(el)
{
var start = 0, end = 0, normalizedValue, range,
textInputRange, len, endRange;
if (typeof el.selectionStart == "number" && typeof el.selectionEnd == "number") {
start = el.selectionStart;
end = el.selectionEnd;
} else {
range = document.selection.createRange();
if (range && range.parentElement() == el) {
len = el.value.length;
normalizedValue = el.value.replace(/\r\n/g, "\n");
// Create a working TextRange that lives only in the input
textInputRange = el.createTextRange();
textInputRange.moveToBookmark(range.getBookmark());
// Check if the start and end of the selection are at the very end
// of the input, since moveStart/moveEnd doesn't return what we want
// in those cases
endRange = el.createTextRange();
endRange.collapse(false);
if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
start = end = len;
} else {
start = -textInputRange.moveStart("character", -len);
start += normalizedValue.slice(0, start).split("\n").length - 1;
if (textInputRange.compareEndPoints("EndToEnd", endRange) > -1) {
end = len;
} else {
end = -textInputRange.moveEnd("character", -len);
end += normalizedValue.slice(0, end).split("\n").length - 1;
}
}
}
}
return {
start: start,
end: end
};
}
function isBrowserIE6()
{
var ret = false;
if(($.browser.msie) && (parseInt($.browser.version) == 6) && (!this.XMLHttpRequest))
{
ret = true;
}
return ret;
}
function isBrowserIE7()
{
var ret = false;
if(($.browser.msie) && ((parseInt($.browser.version) == 7) && (this.XMLHttpRequest)))
{ //Modification because of IE tester IE7 being detected as IE6
ret = true;
}
return ret;
}
Предыдущая скрипта не работала в IE, потому что к моменту возникновения события onblur()
выбор в IE был уничтожен. Я применил некоторые браузерные условия для IE 6 и 7, но еще не тестировал в IE 8.
Спасибо Тиму Дауну , который помог мне выявить проблему с предыдущей скрипкой.