如何使用JavaScript从文本框控件中获取所选文本

42

我有一个文本框和一个链接按钮。 当我输入一些文本,选择其中一些文本,然后单击链接按钮时,来自文本框的选定文本必须显示在消息框中。

我该怎么做?


当我点击下面文本框的提交按钮时,消息框必须显示Lorem ipsum。因为"Lorem ipsum"被选中了。


如果我从页面上选择任何文本并单击提交按钮,则它可以正常工作,但如果我写入文本框并进行选择,则无法正常工作。因为当我单击其他空间时,文本框的选择会被取消。

现在的问题是,当我从文本框中选择文本并单击任何其他控件或空间时,所选文本必须仍然保持选定状态。

应该如何实现?


我认为你应该查看Firefox的selectionstart/selectionend属性和IE中的textrange,可以参考以下链接: http://www.dedestruct.com/2008/03/22/howto-cross-browser-cursor-position-in-textareas/ - MatthieuGD
6个回答

45

好的,这是我拥有的代码:

function ShowSelection()
{
  var textComponent = document.getElementById('Editor');
  var selectedText;

  if (textComponent.selectionStart !== undefined)
  { // Standards-compliant version
    var startPos = textComponent.selectionStart;
    var endPos = textComponent.selectionEnd;
    selectedText = textComponent.value.substring(startPos, endPos);
  }
  else if (document.selection !== undefined)
  { // Internet Explorer version
    textComponent.focus();
    var sel = document.selection.createRange();
    selectedText = sel.text;
  }

  alert("You selected: " + selectedText);
}

问题是,虽然我在很多网站上提供了适用于Internet Explorer 6的代码,但我无法在当前系统上使其正常工作。也许它对你有用,这就是为什么我提供它的原因。
你要寻找的技巧可能是调用 .focus() 函数将焦点返回到文本区域,以便重新激活选择。
我使用 onKeyDown 事件获得了正确的结果(即所选内容)。
document.onkeydown = function (e) { ShowSelection(); }

所以代码是正确的。问题在于如何在单击按钮时获取选择...我继续搜索。

使用 li 标签绘制的按钮没有成功,因为当我们单击它时,Internet Explorer 会取消先前的选择。但上述代码可以使用简单的 input 按钮。


1
8年前的帖子,我知道。但是无论如何...也许你可以尝试:在按钮单击时调用$('<yourtextboxid>').focus(),然后调用ShowSelection()获取活动元素的部分? - Krishnan
1
这可以更加简单地完成:https://dev59.com/wnVC5IYBdhLWcg3wfxM8#32397146。 - Dan Dascalescu

18

以下是一种更简单的解决方案,它基于文本选择发生在鼠标抬起时的事实,因此我们添加了一个事件监听器:

document.querySelector('textarea').addEventListener('mouseup', function () {
  window.mySelection = this.value.substring(this.selectionStart, this.selectionEnd)
  // window.getSelection().toString();
});
<textarea>
  Select some text
</textarea>
<a href="#" onclick=alert(mySelection);>Click here to display the selected text</a>

这可在所有浏览器中正常工作。

如果你还想通过键盘处理选择,请添加另一个事件监听器keyup,并使用相同的代码。

如果不是因为这个Firefox的bug已于2001年提出(是的,14年前),我们可以将赋值给window.mySelection替换为window.getSelection().toString(),它适用于IE9+和所有现代浏览器,并获取在DOM的非文本区域中进行的选择。


所以你批评了七年前提出的解决方案,却没有指出你的解决方案在IE < 9中不起作用... :-) 好吧,用现代解决方案更新主题是很好的,但不要忘记一些人关心旧浏览器。* https://developer.mozilla.org/en-US/docs/Web/API/Window/getSelection - PhiLho
@PhiLho:令人难以置信的是,它在FF中不起作用 - 该错误已于14年前被报告。更新的答案。 - Dan Dascalescu
1
这个解决方案很好,但是如果光标移出文本区域,事件将不会触发。您必须添加以下代码才能使其在这种情况下工作:document.querySelector('textarea').addEventListener('mouseleave', function () { window.mySelection = this.value.substring(this.selectionStart, this.selectionEnd); }); 然后,当您离开文本区域时,事件也会触发,因此保留您的选择。 - Darxtar
1
鼠标?如果使用键盘进行选择,它能工作吗?您能在您的回答中解决这个问题吗? - Peter Mortensen

4

function disp() {
  var text = document.getElementById("text");
  var t = text.value.substr(text.selectionStart, text.selectionEnd - text.selectionStart);
  alert(t);
}
<TEXTAREA id="text">Hello, How are You?</TEXTAREA><BR>
<INPUT type="button" onclick="disp()" value="Select text and click here" />


1
这个方法可以工作,但是如果你在disp()中有更复杂的代码,当代码从文本区域获取选择(例如构建一个selection-menu),浏览器可能已经清除了它,因为按钮上发生的click事件意味着文本区域接收到了blur事件,这会清除选择。我的答案通过在发生选择时将其保存在变量中来解决这个问题。 - Dan Dascalescu

2

对于Opera、Firefox和Safari浏览器,您可以使用以下函数:

function getTextFieldSelection(textField) {
    return textField.value.substring(textField.selectionStart, textField.selectionEnd);
}

然后,你只需将文本字段元素的引用(如文本区域或输入元素)传递给函数:
alert(getTextFieldSelection(document.getElementsByTagName("textarea")[0]));

或者,如果你想让 <textarea> 和 <input> 拥有自己的 getSelection() 函数:

HTMLTextAreaElement.prototype.getSelection = HTMLInputElement.prototype.getSelection = function() {
    var ss = this.selectionStart;
    var se = this.selectionEnd;
    if (typeof ss === "number" && typeof se === "number") {
        return this.value.substring(this.selectionStart, this.selectionEnd);
    }
    return "";
};

那么,您只需执行以下操作:
alert(document.getElementsByTagName("textarea")[0].getSelection());
alert(document.getElementsByTagName("input")[0].getSelection());

例如。

1
我是jQuery-textrange的忠实粉丝。
以下是一个非常小巧、自包含的示例。下载jquery-textrange.js并将其复制到同一文件夹中。
<!doctype html>
<html>

<head>
    <meta charset="UTF-8">
    <title>jquery-textrange</title>
    <script src="http://code.jquery.com/jquery-latest.min.js"></script>
    <script src="jquery-textrange.js"></script>

    <script>
        /* Run on document load */
        $(document).ready(function() {
            /* Run on any change of 'textarea' **/
            $('#textareaId').bind('updateInfo keyup mousedown mousemove mouseup', function() {

                /* The magic is on this line **/
                var range = $(this).textrange();

                /* Stuff into selectedId. I wanted to
                   store this is a input field so it
                   can be submitted in a form. */
                $('#selectedId').val(range.text);
            });
        });
    </script>
</head>

<body>
    The smallest example possible using
    <a href="https://github.com/dwieeb/jquery-textrange">
       jquery-textrange
    </a><br/>
    <textarea id="textareaId">Some random content.</textarea><br/>
    <input type="text" id="selectedId"></input>

</body>

</html>

1
不需要任何jQuery插件。请查看我的答案 - Dan Dascalescu

0
// jQuery
var textarea = $('#post-content');
var selectionStart = textarea.prop('selectionStart');
var selectionEnd = textarea.prop('selectionEnd');
var selection = (textarea.val()).substring(selectionStart, selectionEnd);

// JavaScript
var textarea = document.getElementById("post-content");
var selection = (textarea.value).substring(textarea.selectionStart, textarea.selectionEnd);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接