我想替换所选文本(如果没有选择任何内容,则在光标位置后插入新文本)。 新文本从另一个文本框输入 我希望能够插入新文本而不先在textarea中单击(聚焦) 含义:首先选择要在textarea中替换的文本,然后在文本框中输入新文本并单击按钮。
<textarea id='text' cols="40" rows="20">
</textarea>
<div id="opt">
<input id="input" type="text" size="35">
<input type="button" onclick='pasteIntoInput(document.getElementById("input").value)' value="button"/>
</div>
function pasteIntoInput(text) {
el=document.getElementById("text");
el.focus();
if (typeof el.selectionStart == "number"&& typeof el.selectionEnd == "number") {
var val = el.value;
var selStart = el.selectionStart;
el.value = val.slice(0, selStart) + text + val.slice(el.selectionEnd);
el.selectionEnd = el.selectionStart = selStart + text.length;
}
else if (typeof document.selection != "undefined") {
var textRange = document.selection.createRange();
textRange.text = text;
textRange.collapse(false);
textRange.select();
}
}
在线示例: link text
答案 0 :(得分:5)
因此,当您从textarea中聚焦并专注于输入标记时,您希望保留选择。
您需要记住选择(文本区域失去焦点时的起点和终点)并强制选择以使其保持不变。
要记住选择,您可以将el.selectionStart
和el.selectionEnd
存储在函数内的两个全局变量中,该函数在textarea标记的onblur()
事件中调用。
然后在pasteIntoInput()
内,您可以考虑将这两点替换。
强制选择 - 检查此解决方案for persisting选择。这使用jquery,但不是普通的javascript。
但是,我不确定该解决方案是否真的有效。我在这里试了http://jsfiddle.net/sandeepan_nits/qpZdJ/1/,但它没有按预期工作。
<强>更新强>
我怀疑焦点消失后是否可以坚持选择。可能选择需要集中在那里,我给出的答案链接试图集中然后选择。在这种情况下,这不会解决您的问题。所以,替代方案可能是 -
伪造带有html div的文本区域。您可以定义一些样式以创建类似效果的选择并应用它onblur()
或使用简单的现成编辑器(如果可用)。
在单独的区域中动态显示选择。检查此demo of jquery fieldSelection plugin。请记住,您已将选择存储在全局变量中以进行实际替换。您只需向用户显示将要替换的选择。我认为像这个演示一样单独显示选择可以节省您的时间,而且看起来也很酷。
但当然要视你的要求而定。
进一步更新
检查http://jsfiddle.net/sandeepan_nits/qpZdJ/2/是否正常工作“在没有焦点的情况下替换textarea内的文字”(如您所愿)但没有选择模糊。我仍然不知道是否可以保持选择模糊。
另一次更新(12月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中尚未测试。
感谢Tim Down帮助我找到前一个小提琴的问题。
答案 1 :(得分:0)
好吧,纠正我错在哪里。
1)当选择textarea中的文本时,单击该按钮,所选文本将被输入中的文本替换。
2)当没有选择文本时,无论光标位置如何,文本都会自动添加到textarea的最末端。
如果这些是唯一的规定,那么这个javascript就足够了,否则我需要更多关于你想要它做什么的信息。
function pasteIntoInput(text) {
el=document.getElementById("text");
el.focus();
if (typeof el.selectionStart == "number" && typeof el.selectionEnd == "number" && el.selectionStart != el.selectionEnd) {
var val = el.value;
var selStart = el.selectionStart;
el.value = val.slice(0, selStart) + text + val.slice(el.selectionEnd);
el.selectionEnd = el.selectionStart = selStart + text.length;
}
else
el.value += text;
}
很抱歉,我无法获得更多帮助,了解该功能的使用会有所帮助,所以我可以给出所需的动作。
答案 2 :(得分:0)
这是基于上述答案和更多想法的替代解决方案 仅适用于IE(其他浏览器默认支持此功能)。
需要进行更多测试(我在IE8中进行了测试)
<script type="text/javascript">
var pos = 0;
var len = 0;
function pasteIntoInput(text) {
var el = document.getElementById("text");
el.focus();
if (typeof el.selectionStart == "number" && typeof el.selectionEnd == "number") {
var val = el.value;
var selStart = el.selectionStart;
el.value = val.slice(0, selStart) + text + val.slice(el.selectionEnd);
el.selectionEnd = el.selectionStart = selStart + text.length;
}
else if (typeof document.selection != "undefined") {
//var textRange = document.selection.createRange();
var textRange = el.createTextRange();
// el.focus();
if (len > 0) { //something selected, so replace
textRange.collapse(true);
textRange.moveEnd('character', pos+len);
textRange.moveStart('character', pos);
textRange.select();
textRange.text = text;
}
else {
textRange.collapse(true);
textRange.moveEnd('character', pos);
textRange.moveStart('character', pos);
textRange.text = text;
textRange.select();
}
el.focus();
}
}
function GetCaretPosition(txtarea) {
pos = 0;
if (document.selection) {
// get current selection
var range = document.selection.createRange();
if (range.text.length>0)
len=range.text.length;
// get full range
var rangeFull = document.body.createTextRange();
rangeFull.moveToElementText(txtarea);
var sel_start;
for (sel_start = 0; rangeFull.compareEndPoints('StartToStart', range) < 0; sel_start++) {
rangeFull.moveStart('character', 1);
}
pos = sel_start;
}
}
</script>
答案 3 :(得分:0)
一个jquery插件,用于在文本区域中获取选择索引的开始和结束。上面的javascript代码对IE7和IE8没有用,并且给出了非常不一致的结果,所以我编写了这个小的jquery插件。 允许临时保存选择的开始和结束索引,并在以后高亮显示选择。
这里有一个工作示例和简要版本: http://jsfiddle.net/hYuzk/3/
更多详细信息版本以及评论等在这里: http://jsfiddle.net/hYuzk/4/
// Cross browser plugins to set or get selection/caret position in textarea, input fields etc for IE7,IE8,IE9, FF, Chrome, Safari etc
$.fn.extend({
// Gets or sets a selection or caret position in textarea, input field etc.
// Usage Example: select text from index 2 to 5 --> $('#myTextArea').caretSelection({start: 2, end: 5});
// get selected text or caret position --> $('#myTextArea').caretSelection();
// if start and end positions are the same, caret position will be set instead o fmaking a selection
caretSelection : function(options)
{
if(options && !isNaN(options.start) && !isNaN(options.end))
{
this.setCaretSelection(options);
}
else
{
return this.getCaretSelection();
}
},
setCaretSelection : function(options)
{
var inp = this[0];
if(inp.createTextRange)
{
var selRange = inp.createTextRange();
selRange.collapse(true);
selRange.moveStart('character', options.start);
selRange.moveEnd('character',options.end - options.start);
selRange.select();
}
else if(inp.setSelectionRange)
{
inp.focus();
inp.setSelectionRange(options.start, options.end);
}
},
getCaretSelection: function()
{
var inp = this[0], start = 0, end = 0;
if(!isNaN(inp.selectionStart))
{
start = inp.selectionStart;
end = inp.selectionEnd;
}
else if( inp.createTextRange )
{
var inpTxtLen = inp.value.length, jqueryTxtLen = this.val().length;
var inpRange = inp.createTextRange(), collapsedRange = inp.createTextRange();
inpRange.moveToBookmark(document.selection.createRange().getBookmark());
collapsedRange.collapse(false);
start = inpRange.compareEndPoints('StartToEnd', collapsedRange) > -1 ? jqueryTxtLen : inpRange.moveStart('character', -inpTxtLen);
end = inpRange.compareEndPoints('EndToEnd', collapsedRange) > -1 ? jqueryTxtLen : inpRange.moveEnd('character', -inpTxtLen);
}
return {start: Math.abs(start), end: Math.abs(end)};
},
// Usage: $('#txtArea').replaceCaretSelection({start: startIndex, end: endIndex, text: 'text to replace with', insPos: 'before|after|select'})
// Options start: start index of the text to be replaced
// end: end index of the text to be replaced
// text: text to replace the selection with
// insPos: indicates whether to place the caret 'before' or 'after' the replacement text, 'select' will select the replacement text
replaceCaretSelection: function(options)
{
var pos = this.caretSelection();
this.val( this.val().substring(0,pos.start) + options.text + this.val().substring(pos.end) );
if(options.insPos == 'before')
{
this.caretSelection({start: pos.start, end: pos.start});
}
else if( options.insPos == 'after' )
{
this.caretSelection({start: pos.start + options.text.length, end: pos.start + options.text.length});
}
else if( options.insPos == 'select' )
{
this.caretSelection({start: pos.start, end: pos.start + options.text.length});
}
}
});