如何从单击按钮的输入中获取选定的文本?

How to get selected text from input on button click?

我试图在单击按钮时在 <input> 中获取所选文本。

我已成功 window.getSelection() 获取选定的文本,但是当我单击按钮时,输入的焦点和选定的文本都丢失了。

我知道有解决方案——我已经看到一两个 jQuery 库——但我正在寻找一个(希望简单的)vanilla JS 解决方案。

<p>Select some text then click the button (doesn't work)</p>
<input type="text" size="20" value="select something">
<button id="btn">alert selection</button>

<script>
    document.getElementById('btn') 
        .addEventListener('click', function() {
            alert(window.getSelection().toString());
        });
</script>

<p>Select some text and see it alerted (works)</p>
<input id="input" type="text" size="20" value="select something">
<script>
    document.getElementById('input')
        .addEventListener('click', function() {
            alert(window.getSelection().toString());
        });
</script>

编辑


针对下面发布的解决方案,我需要避免的一个问题是之前的选择实际上被 缓存 。如果用户有目的地取消选择文本(不是通过单击此特定按钮),我需要它 而不是 记住旧的选择。最终目标是在单击按钮时修改选定的子字符串,如果没有选择任何内容,则仅附加到它。

已编辑:

blur 时使用 post(因为它更好地处理 select 范围)和 setTimeout,并且仅在以下情况下取消超时它直接关注那个按钮。

然后点击事件后,清除select范围。

var input = document.getElementById('test');
var btn = document.getElementById('btn');
var blur = null;
var clearSelect = function() {
  input.setSelectionRange(0, 0);
};
input
  .addEventListener('blur', function() {
    blur = setTimeout(clearSelect, 0);
  });
btn
.addEventListener('focus', function() {
  if (blur !== null) {
    clearTimeout(blur);
    blur = null;
  }
});
btn
.addEventListener('click', function() {
  alert(input.value.substring(input.selectionStart, input.selectionEnd));
  clearSelect();
});
<p>Select some text then click the button</p>
<input type="text" size="20" id="test" value="select something">
<button id="btn">alert selection</button>

如果FocusEvent.relatedTarget becomes a standard, and IE<9 is not in concern (or you just love to embrace the newest technology), you can use write the logic as posted的规范,可以使代码更简单。

var input = document.getElementById('test');
var btn = document.getElementById('btn');
var clearSelect = function() {
  input.setSelectionRange(0, 0);
};
input
  .addEventListener('blur', function(e) {
    // e.relatedTarget would be the elment that will get focus, if click on something that can't be focus
    // the value will be null.
    if (e.relatedTarget !== btn) {
      clearSelect();
    }
  });
btn
.addEventListener('click', function() {
  alert(input.value.substring(input.selectionStart, input.selectionEnd));
  // You can either focus back to the input or just clear the selection range in the input.
  //input.focus();
  clearSelect();
});
<p>Select some text then click the button</p>
<input type="text" size="20" id="test" value="select something">
<button id="btn">alert selection</button>

给你。一个干净的解决方案,无需使用第二个输入字段。 http://jsfiddle.net/5kq4yecz/1/

document.getElementById('btn').addEventListener('click', function() {
  alert(test.value.substring(test.selectionStart, test.selectionEnd));
});
<p>Select some text then click the button</p>
<input type="text" size="20" id="test" value="select something">
<button id="btn">alert selection</button>

我最终想出了一个解决方法,使用 FocusEvent.relatedTarget 检查输入是否在选择按钮时失去焦点。

FocusEvent.relatedTargetWindow.getSelection() 在 IE<9 中不受支持,并且在发布时尚未正式成为规范的一部分。我觉得他们的广泛采用表明他们将可能保持稳定。

<p>Select some text then click the button</p>
<input id="input" type="text" size="20" value="select something">
<button id="btn">alert selection</button>

<script>
    var input = document.getElementById('input');
    var btn = document.getElementById('btn');

    btn.addEventListener('click', function() {
        input.focus();
        var selection = window.getSelection().toString();
        alert(selection);
    });

    input.addEventListener('blur', function(e) {
        if (e.relatedTarget !== btn) {
            input.setSelectionRange(0, 0);
        }
    });
</script>