chrome setSelectionRange() 在 oninput 处理程序中不起作用

问题描述 投票:0回答:5

我正在使用一些自动完成代码。

setSelectionRange()
用于选择在
oninput
事件处理程序中完成的文本。它至少在 Firefox 14 中有效,但在 Chrome(6, 17) 中无效。

演示问题的简化代码片段如下:

<input type='text' oninput='select()' />
function select(e){
    var s = this.value;
    if (s.length)
        this.setSelectionRange(s.length-1, s.length);
}

我在chrome中调试了代码,发现在执行完

setSelectionRange()
后,文本首先被选中,但随后选择消失了。

如果我将处理程序绑定到

onclick
而不是
oninput
,如下所示:

<input type='text' onclick='select()' />

然后两个浏览器都可以正常工作。

任何人都可以给我一些在 Chrome 中进行选择的线索吗?

javascript google-chrome cross-browser html-input
5个回答
19
投票

您的代码存在一些问题,即传递到

select()
函数的参数是错误的:
this
将是
window
并且
e
将是未定义的。此外,在
select()
属性中使用
oninput
作为函数名称会导致问题,因为 select 将解析为输入本身的
select()
方法。更好的方法通常是在脚本中设置事件处理程序,而不是通过事件处理程序属性。

但是,即使纠正了这些问题,问题仍然存在。可能会在浏览器在 Chrome 中移动插入符号之前触发

input
事件。一个简单的解决方法是使用计时器,尽管这不是最佳选择,因为用户有可能在计时器触发之前输入另一个字符。

演示:http://jsfiddle.net/XXx5r/2/

代码:

<input type="text" oninput="selectText(this)">

<script type="text/javascript">
function selectText(input) {
    var s = input.value;
    if (s.length) {
        window.setTimeout(function() {
            input.setSelectionRange(s.length-1, s.length);
        }, 0);
    }
}
</script>

1
投票

    
    
    var $input = document.getElementById('my_id');
    
    $input.onfocus = function () {
       $input.setSelectionRange(0, 7);
    }
    $input.focus();
    
    
<input type='text' id='my_id' value="My text for example." />


1
投票

例如在 Angular 上你可以这样做:

@ViewChild('input', { static: false }) inputElement: ElementRef;

focus(){    
    setTimeout(() => {
        this.inputElement.nativeElement.focus();
        this.inputElement.nativeElement.setSelectionRange(this.valueInput.length, this.valueInput.length);
    });
}

0
投票

我认为

setTimeout
不是最好的解决方案。您只需要在使用之前调用事件处理程序
setSelectionRange
。我用这个:

e.currentTarget.value = previousValue;
onChange(e);
e.currentTarget.setSelectionRange(startPosition, endPosition);

0
投票

我使用的是 React,这在 Firefox 和 Chrome 上都对我有用。首先执行选择所需子字符串的代码,然后调用 focus 并确保它最后运行,将其包装在

setTimeout

onFocus={(e: React.FocusEvent<HTMLInputElement>) => {
    e.stopPropagation();

    const start = 0;
    const end = value.lastIndexOf(".");

    if (e.target.setSelectionRange) {
        e.target.setSelectionRange(start, end);
    } else if (typeof e.target.selectionStart !== "undefined") {
        e.target.selectionStart = start;
        e.target.selectionEnd = end;
    }
    setTimeout(() => {
        e.target.focus();
    }, 0);
}}

© www.soinside.com 2019 - 2024. All rights reserved.