你能否在JavaScript中设置和/或更改用户的文本选择?

32

在 JavaScript 中,有多种方法用于访问用户的文本选择并创建文本选择(或范围)- 请参见http://www.quirksmode.org/dom/range_intro.html

根据该页面,您可以通过编程方式创建范围,并访问其中的文本。但是这样做不会更改用户的文本选择,也不会使用户拥有所选的文本(如果他们还没有)。

你能否在 JavaScript 中设置和/或更改用户的文本选择?


2
你的意思是让页面中的某些文本突然出现被选择吗?带蓝色高亮和一切? - Shadow The Spring Wizard
1
@Shadow:是的,就是这样。 - Paul D. Waite
2个回答

41

是的,你可以在所有浏览器中获取一个或多个 Range 或者一个 TextRange 从用户的选区,并且 RangeTextRange 都有改变选区内容的方法。

更新

你可以通过在大多数浏览器中创建一个 Range 并将其添加到 Selection 对象中,或者在 IE <= 8 中创建一个 TextRange 并调用其 select() 方法来设置用户的选择。

例如,要将选择设置为包含元素内容:

function selectElementContents(el) {
    if (window.getSelection && document.createRange) {
        var sel = window.getSelection();
        var range = document.createRange();
        range.selectNodeContents(el);
        sel.removeAllRanges();
        sel.addRange(range);
    } else if (document.selection && document.body.createTextRange) {
        var textRange = document.body.createTextRange();
        textRange.moveToElementText(el);
        textRange.select();
    }
}

在非IE浏览器中,Selection对象有几种方法可以用来改变用户的选择。如果您能更具体地说明想要如何更改选择,那么帮助会更容易。


1
啊,对不起,我没有很好地表达问题——实际上我想设置用户在没有选择文本时的文本选择。 - Paul D. Waite
能否同时选择不同的范围?我想要能够选择多个不连续的文本部分。 - Techsin
1
@Techsin:是的,但只能在Firefox中。调用“addRange()”以选择要选择的每个范围。 - Tim Down
@Griddo:只有当您不知道范围偏移可以相对于元素而不仅仅限于文本节点时,才会出现意外情况。此外,您不应仅将选择偏移量限制为文本节点(考虑不包含文本的元素,如 <br><hr>)。 - Tim Down
@TimDown 你说得完全正确。这只是一个旁注,为那些可能面临同样问题的人提供帮助,并且(关于文本节点)作为一个例子来说明我的困惑,但绝不是一般建议或经验法则。对我来说,<span>Hello World!</span> 上的 selectNodeContents 可视选择 "Hello World!",但其 endOffset 却是 1 而不是 12,这非常不直观。一旦您熟悉了节点、选择和范围的概念,它就完全有意义了。 - Gerrit-K
显示剩余2条评论

9

2021年更新

Selection API 可以帮助我们实现这个功能。与其创建一个 new Selection() 对象(看似直觉,但并不起作用),window.getSelection() 总是返回一个 Selection 对象 - 即使用户没有选中任何文本! 然后,可以使用setBaseAndExtent() 方法将特定节点突出显示 - 这将更改用户选择的任何内容(即使未选择任何内容)以匹配您指定的内容。

下面的示例会将这个 StackOverflow 页面中的问题部分进行高亮显示

const selection = window.getSelection()
const headerElement = document.querySelector('#question-header a')
selection.setBaseAndExtent(headerElement,0,headerElement,1)

浏览器支持看起来相当不错,尽管如果您仍然需要支持IE 8,window.getSelection将无法工作。 - Paul D. Waite
2
还有,现在已经是2021年了兄弟。 - Paul D. Waite
2
@PaulD.Waite 说到2021年 - IE8? - mikemaccana
当然,2021年支持IE11的人数显然相当少。这个答案很简短,使用了更简单的技术,并提供了指向MDN实际规范的链接。 - mikemaccana
根据 TypeScript,window.getSelection 可能会返回 null。 - Charlie Martin
显示剩余2条评论

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