如何防止在html中模糊(焦点丢失)时取消选择所选文本

How to prevent deselection of selected text on blur (focus lost) in html

本文关键字:取消 选择 文本 html 何防止 模糊 焦点      更新时间:2023-12-21

我已经对这个听起来很简单的问题进行了几天的研究,但没有看到任何结果。

简言之,我的问题如下:我想在某个输入字段中选择文本,将焦点转移到另一个字段(或者通常说其他元素),但不要丢失我选择的文本。

这种情况可能对应于一个用例,在该用例中,我在字段中选择文本,右键单击并显示自定义弹出菜单,但不希望失去所选文本的焦点,因为我想对以前选择的文本进行一些操作。

一个小的代码测试示例是(对于我最初的简单场景——在这里,当第二个输入字段获得焦点时,我强制选择文本):

<html>
<head>
  <script src="http://code.jquery.com/jquery-latest.js"></script>
</head>
<body>
    <input type="text" id="text1" size="20" value="Test1"/>
    <input type="text" id="text2" size="20" value="Test2"/>
    <script>
    $('#text2').focus( function (evt) {
        var target = $('#text1')[0];
        target.select();
        console.log('active/focused element: ' + document.activeElement.id);
    });
    </script>
</body>
</html>

我一直在SO和web上搜索解决方案,但没有看到太多帮助。我甚至不确定这是否真的可能(由于模糊和选择丢失以及焦点和选择之间的联系)。我在另一个SO答案中看到了一个名为preventDeselect的样式属性——这不起作用,我甚至没有这样的文档或浏览器支持。

我对此很挣扎,希望能得到一些帮助:甚至说我根本做不到,或者可能还有一些路要走。

更新:顺便说一句,我的用户场景是指文本选择和上下文菜单,这是一个常见的场景(我忘了提一下):只需在此页面(或输入类型字段)中选择一些文本,然后右键单击即可获得浏览器的默认上下文菜单-我的场景不同之处在于,我想使用自定义菜单,但其行为与浏览器的上下文菜单类似,该菜单通常允许选择一些文本、剪切/复制所选内容、在上下文菜单中导航而不会丢失所选文本。所以我认为这应该是可能的:)用上下文菜单做所有这些事情,并且仍然有你的选择。

尝试回答以下部分问题:

这种情况可能对应于我选择文本的用例在字段中,右键单击并显示自定义弹出菜单,但不要希望失去所选文本的焦点,因为我想做一些操作。

对于这个用例,我创建了一个快速小提琴:http://jsfiddle.net/4XE9a/1/

注意:我使用@David答案中的相同getSelection函数。

如果您选择任何文本,然后右键单击输入,则会出现一个自定义弹出菜单。单击"选项1"。您会发现,即使焦点已转移到该锚点标记,所选内容也不会丢失。

然而,对于你关于焦点转移到另一个文本框的问题的第二部分,@David的回答就足够了。

更新:(评论后

请查看此更新的小提琴:http://jsfiddle.net/783mA/1/

现在,当您选择一些文本并右键单击输入时,它将显示带有三个选项的自定义弹出菜单。使用选项卡导航并按空格键,或单击突出显示的选项。(由于时间不足,我无法实现向上/向下箭头键,但概念保持不变)

这表明了您在注释中的问题,即在导航菜单时所选内容仍未丢失。

注意:您希望在视觉上保持所选内容高亮显示,并且在单击其他位置时不会丢失所选内容。请注意,这是不可能的,因为文本选择行为是操作系统实现的。浏览器、html等在这里不起作用。只要单击所选内容上下文之外的任何位置,文本选择就会丢失。这是因为一旦您单击外部任何位置,系统就会开始期待新的选择。但是,没有文本表面的控件除外。按钮、滚动条箭头等不会导致选择丢失。

要查看这种行为,请在fiddle中选择一些文本,然后单击左侧窗格上的任何下拉列表。文本选择不会丢失,即使在视觉上也是如此。

这就是为什么在上面的新小提琴中,我特意用按钮来演示。

您可以将每个选择保存在一个间隔中,然后根据需要进行检索。这里有一个例子,当输入有焦点并清除模糊的间隔时,拉动选择:

function getSelection(elm) {
    var start = elm.selectionStart;
    var end = elm.selectionEnd;
    return elm.value.substring(start, end);
}
$('input').focus(function() {
    var self = this;
    $(this).data('interval', setInterval(function() {
        $(self).data('selection', getSelection(self));
    },20));
}).blur(function() {
    clearInterval($(this).data('interval'));
});

现在你可以像这样:

$('#text2').focus(function() {
    console.log('selection in #text1 was: '+$('#text1').data('selection'));
});

演示:http://jsfiddle.net/qCCY5/