替换textarea内的文本而不用重点 [英] Replacing text inside textarea without focus

查看:160
本文介绍了替换textarea内的文本而不用重点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要替换选定的文本(或者如果没有选择任何内容,则在光标位置之后插入新的文本)。
新文本是从另一个文本框输入的。

我希望能够插入新文本而不必单击textarea中的第一个(聚焦)。

含义:first select文本替换textarea,然后在文本框中输入新文本并点击按钮。

 < textarea id ='text' cols =40rows =20> 
< / textarea>

< div id =opt>
< input id =inputtype =textsize =35>
< input type =buttononclick ='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();




$ b在线示例
链接文本

解决方案

所以,当你关注textarea并关注输入标签时,你想要坚持选择。



您需要记住选择(文本区域失去焦点时的开始和结束点)并强制选择,以便它保持不变。



要记住选择,您可以将 el.selectionStart el.selectionEnd 存入在 onblur()事件的textarea标记处调用一个函数内的两个全局变量。

然后在你的 pasteIntoInput()您可以考虑将这两个点替换。



强制选择 - 检查此解决方案坚持选择。然而,这使用jquery,而不是纯javascript。



然而,我不确定解决方案是否真正起作用。我在这里尝试过 http://jsfiddle.net/sandeepan_nits/qpZdJ/1/ 但它不会按预期工作。



更新



我怀疑它是否在焦点消失后可以坚持选择。可能的选择需要关注于那里,我给出的答案链接试图关注并选择。在这种情况下,这不会解决您的问题。所以,替代方案可能是 - 伪造带有html div的文本区域。您可以定义一些样式来创建一个类似效果的选择,并将其应用于 onblur()或使用简单的现成编辑器(如果可用)。

  • 在单独的区域中动态显示选择。查看 jquery fieldSelection插件的演示。请记住,您已经将选择存储在全局变量中用于实际替换。您只需向用户显示将被替换的选择。我认为像这个演示一样单独显示选择可以节省您的时间,而且看起来也很酷。


  • $ b

    进一步更新

    检查 http://jsfiddle.net/sandeepan_nits/qpZdJ/2/ 为工作替换textarea内的文本,无焦点(像你想要的),但没有选择模糊。我仍然不知道是否可以保持选择模糊。



    另一个更新(12月21日)



    针对IE和其他浏览器的工作解决方案
    http://jsfiddle.net/sandeepan_nits/qpZdJ/24/



    以下是相同的代码: -



    html -

     < textarea id ='text'cols =40rows =20 onbeforedeactivate = storeSelectionIeCase();的onblur = storeSelectionOthersCase(); > 
    < / textarea>

    < div id =opt>
    < input id =inputtype =textsize =35>
    < input type =buttononclick ='pasteIntoInput(document.getElementById(input)。value)'value =button/>

    < / div>

    以及所有js

      var storedSelectionStart = null; 
    var storedSelectionEnd = null;

    function pasteIntoInput(text)
    {

    el = document.getElementById(text);

    el.focus(); ((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();



    函数storeSelectionOthersCase()
    {
    if(!(isBrowserIE6()|| isBrowserIE7()))
    {
    storeSelection();
    }
    else
    {
    return false;



    $ b函数storeSelectionIeCase()
    {
    if((isBrowserIE6()|| isBrowserIE7()))
    {
    storeSelection();
    }
    else
    {
    return false;



    $ b函数storeSelection()
    {
    //获得选择
    el = document.getElementById(文本);

    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);

    $ b $ 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\\\
    / g,\\\
    );

    //创建一个只工作在输入中的TextRange
    textInputRange = el.createTextRange();
    textInputRange.moveToBookmark(range.getBookmark());

    //检查选择的开始和结束是否在输入的最后
    //,因为moveStart / moveEnd不会返回我们想要的
    / /在这些情况下
    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(\\\
    )。length - 1;

    if(textInputRange.compareEndPoints(EndToEnd,endRange)> -1){
    end = len;
    } else {
    end = -textInputRange.moveEnd(character,-len);
    end + = normalizedValue.slice(0,end).split(\\\
    )。length - 1;
    }
    }
    }
    }

    返回{
    开始:开始,
    结束:结束
    } ;
    }

    函数isBrowserIE6()
    {
    var ret = false; (($。browser.msie)&&(parseInt($。browser.version)== 6)&&(!this.XMLHttpRequest))
    {
    ret = true;
    }
    return ret;
    }

    函数isBrowserIE7()
    {
    var ret = false; (($。browser.msie)&((parseInt($。browser.version)== 7)&&(this.XMLHttpRequest)))
    {//修改由于IE测试IE7被检测为IE6
    ret = true;
    }
    return ret;

    以前的小提琴在IE中不起作用,因为在 onblur()事件触发,选择在IE中被销毁。我已经为IE 6和7应用了一些基于浏览器的条件,但未在IE 8中测试过。



    感谢 Tim Down ,他帮助我找出前一个小提琴的问题。


    I want to replace selected text(or insert new text after cursor position if nothing is selected). The new text is entered from another textbox.
    I want to be able to insert new text without clicking first (focusing) in the textarea.
    meaning: first select text to replace inside textarea, then enter new text into the textbox and click the button.

    <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();
      } 
    }  
    

    Online example: link text

    解决方案

    So, you want to persist the selection when you focus out of the textarea and focus on the input tag.

    You need to remember the selection (start and end points when the text area loses focus) and force the selection so that it persists.

    To remember the selection, you can store the el.selectionStart and el.selectionEnd in two global variables inside a function which is called at onblur() event of textarea tag.

    Then inside your pasteIntoInput() you can consider those two points for replacement.

    To force selection - Check this solution for persisting the selection. This uses jquery however, not plain javascript.

    However, I am not sure whether the solution actually works. I tried it here http://jsfiddle.net/sandeepan_nits/qpZdJ/1/ but it does not work as expected.

    Updates

    I doubt if it is possible to persist selection after focus is gone. Probably selection needs focus to be there and the answer link that I gave tries to focus and then select. In that case this will not solve your problem. So, the alternatives could be -

    • faking a text area with an html div. You can define some styles to create a selection like effect and apply it onblur() or use a simple readymade editor if available.

    • Displaying the selection dynamically in a separate area. Check this demo of jquery fieldSelection plugin . Remember that you are already storing the selection in global variables for the actual replacement. You only need to display to the user the selection which will be replaced. I think displaying the selection separately like this demo saves your time and it looks cool too.

    But depends on your requirement of course.

    Further Update

    Check http://jsfiddle.net/sandeepan_nits/qpZdJ/2/ for a working "Replacing text inside textarea without focus" (like you want) but without the selection on blur. I still don't know whether it is possible to keep the selection on blur.

    Another Update (21st December)

    Working solution for IEs as well as other browsers http://jsfiddle.net/sandeepan_nits/qpZdJ/24/

    Here is the same code:-

    The 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>
    

    and all the 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;
    }
    

    The previous fiddle was not working in IEs because by the time the onblur() event fires, the selection is destroyed in IE. I have applied some browser based conditions for IE 6 and 7, but not tested yet in IE 8.

    Thanks to Tim Down who helped me in identifying the problem with the previous fiddle.

    这篇关于替换textarea内的文本而不用重点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆